从服务端下载图片(主线程阻塞,消息队列机制,从网上下载图片)
来源:互联网 发布:红外线空调遥控器软件 编辑:程序博客网 时间:2024/05/09 12:16
看着大神的技术各种高大上,自己怎么能落后呢?
好好加油吧,骚年。对昨天的从服务端下载图片进行复习。
主线程阻塞:
1,UI停止刷新,应用无法响应用户的操作。
2,耗时操作不应该放在主线程中。
3,ANR
application not responding
应用无响应异常
主线程阻塞时间过长,就会抛出ANR
4,主线程又称为是UI线程,因为只有在主线程,才能刷新UI
消息队列机制
这里接触到了消息队列机制:
主线程创建的时候,系统会同时创建消息队列对象(MessageQueue)和消息轮询器对象(Looper)。
消息轮询器的作用是:不停的检测消息队列中是否有消息(Message),
消息队列一旦有消息,轮询器就会把消息对象传给消息处理器(Handler),
消息处理器就会调用handlerMessage方法来处理这条消息,handlerMessage方法运行在主线程,所以可以刷新UI
总结:只要有消息队列有消息,handlerMessage方法就会调用,
子线程如果需要刷新UI,只要往队列中发送一条消息,触发handlerMessage方法即可,,子线程使用处理器对象的sendMessage方法发送消息。
实验的代码:
package com.example.xm.imageview;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.ImageView;import android.widget.Toast;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;public class MainActivity extends AppCompatActivity { ImageView iv; Handler handler = new Handler(){ //此方法在主线程中调用,可以用来刷新UI @Override public void handleMessage(Message msg) { switch (msg.what){ case 1: //把位图对象显示在imageview iv.setImageBitmap((Bitmap) msg.obj); break; case 0: Toast.makeText(MainActivity.this,"请求失败",Toast.LENGTH_LONG).show(); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); }public void click(View view){ //下载图片 /* 1,确定网站,1,确定网站,,原来模拟器默认把127.0.0.1和localhost当做本身了, 在模拟器上可以用10.0.2.2代替127.0.0.1和localhost,另外如果是在局域网环境可以用 192.168.0.x或者192.168.1.x(根据具体配置)连接本机,这样应该就不会报错了 */ final String path = "http://10.0.2.2:8080/liu.png"; final File file = new File(getCacheDir(),getFileName(path)); //判断缓存中是否存在 if (file.exists()){ //如果缓存中存在,就从缓存中取 System.out.println("从缓存中取出"); Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath()); iv.setImageBitmap(bm); }else{ //如果缓存不存在,就从网上下载 System.out.println("从网上下载"); Thread t = new Thread(){ @Override public void run() { try { //2,把网址封装成一个url对象 URL url = new URL(path); //3,获取客户端和服务端的连接对象,此时ahi没有建立连接 HttpURLConnection connection =(HttpURLConnection) url.openConnection(); //4,对连接进行初始化 //设置请求方法,注意是大写 connection.setRequestMethod("GET"); //设置连接超时 connection.setConnectTimeout(5000); //设置读取超时 connection.setReadTimeout(5000); //5,发送请求,与服务器建立连接 connection.connect(); //如果响应码是200,说明请求成功 if (connection.getResponseCode() == 200){ //获取服务器响应头中的流,流中的数据就是客户端请求的数据 InputStream is = connection.getInputStream(); //读取服务器返回流中的数据,然后写入到本地的文件中,缓存起来 FileOutputStream fos = new FileOutputStream(file); byte [] b = new byte[10024]; int len = 0; while ((len = is.read(b)) != -1){ fos.write(b,0,len); } fos.close(); //读取出流中的数据,并构成位图 //Bitmap bm = BitmapFactory.decodeStream(is); Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath()); Message message = new Message(); //消息对象可以携带数据,这里把bm放在message.obj中 message.obj = bm; //把消息发送至主线程的消息队列中 message.what =1; handler.sendMessage(message); }else { Message message = handler.obtainMessage(); message.what = 0; handler.sendMessage(message); } } catch (Exception e) { e.printStackTrace(); } } }; t.start(); } }
0 0
- 从服务端下载图片(主线程阻塞,消息队列机制,从网上下载图片)
- 从网上下载图片
- WebClient 从网上下载图片
- android从网上下载图片
- Android从网上下载图片
- HttpURLConnection从网上下载图片
- Delphi 从网上下载HTML、图片文件
- 从网上下载图片到本地
- android异步从网上下载图片
- AsyncTask异步从网上下载图片
- Python从网上下载图片的方法
- 从服务器下载图片
- 从网上下载图片存到沙盒里的Documents里面(图片的缓存)
- java代码实现从网上直接下载图片或者网页
- Android 从网上下载图片并显示到ListView上
- JAVA编写一个程序从网上下载一张图片
- iOS多线程使用实例(异步下载图片的时候不会阻塞主线程的执行)
- Android中从网上下载一张图片显示进度并显示下载好的图片
- Servlet——HttpServletRequest对象详解
- CharSequence与String以及stringbuffer与stringbuilder--Android学习笔记6-2
- 【单片机】[stm8] - 使用库函数时,减少ROM占用的方法
- 拓扑排序的应用(zoj3780)
- ios事件慢慢整理
- 从服务端下载图片(主线程阻塞,消息队列机制,从网上下载图片)
- nyoj 星际之门(一)
- js之事件冒泡和事件捕获详细介绍
- Foundation => Objective-C _ Part4
- 关于输入一个ID后,该ID的2个类别展示的问题
- HTTP结构
- P2P实时音视频之NAT穿越
- MS三轮面试总结
- FZU 2155(并查集的删除)