参考教程:iMooc关于Handler,http://www.imooc.com/learn/267

参考资料:Google提供Android文档Communicating with the UI Thread

Handler的作用:

  Android开发中不允许UI主线程之外的线程更新,那么在主线程下建立Handler对象用于接收其他线程传来的数据(由Message携带)更新UI是Android提供的方法之一,另一个是我们熟知的更加轻量的AsyncTask类,这里不做展开,详细的Handler+Thread与AsyncTask的区别见AsyncTask和Handler的优缺点比较。将耗时的操作用其他Thread执行,执行完毕后传送给Handler对象一个Message,然后由Handler将传来的数据交给UI主线程。

  Handler要解决的根本问题是Android线程并发,如果没有相应的机制约束各线程的协作并发,很容易导致开发上和运行上的混乱。Android处理多线程的方式也不是传统上的加锁机制(性能因素吧),而是MessageQueue,即消息队列,开发者可以直接控制消息队列的显示顺序和方式,这样就不会产生数据的同步混乱的问题了。

  写一个小Demo,帮助理解Handler的使用。用新建Thread处理下载图片和显示图片两个操作。

  在MainActivity的onCreate方法中添加一个新的线程:

        //初始化View        imageView = (ImageView) findViewById(R.id.imageView);        //添加Thread用于下载图片和更新UI        new Thread(new MyRunnable()).start();     

  

  MyRunnable类

public class MyRunnable implements Runnable {    Activity mActivity;    private Message msg;    private Bitmap imageBitmap;    private static final String urlData = "http://sfault-avatar.b0.upaiyun.com/166/281/166281916-1140000000145114_huge128";    @Override    public void run() {        msg  = new Message();        imageBitmap = getHttpImage(urlData);        msg.obj = imageBitmap;                //将imageBitmap用msg传给MainActivity中的handler        MainActivity.handler.sendMessage(msg);    }    //用网址 urlData 读取图片的Bitmap    private Bitmap getHttpImage(String urlData) {        Bitmap bitmap = null;        try {            URL url = new URL(urlData);            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();            httpURLConnection.setConnectTimeout(5*1000);            httpURLConnection.setDoInput(true);            httpURLConnection.connect();            InputStream inputStream = httpURLConnection.getInputStream();            bitmap = BitmapFactory.decodeStream(inputStream);            inputStream.close();            httpURLConnection.disconnect();        } catch (Exception e)        {            // TODO Auto-generated catch block            e.printStackTrace();        }        return bitmap;    }}

  回到MainActivity中,初始化handler,并重写其handleMessage方法,代码如下:

public static Handler handler = new Handler(Looper.getMainLooper()){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            //从msg中获取图片的bitmap            Bitmap bitmap = (Bitmap) msg.obj;            //更新UI            imageView.setImageBitmap(bitmap);        }    };

总结,用Handler+Thread的方式执行单一线程确实比较繁琐,用AsyncTask会更简洁高效。但是在比较复杂的多线程应用场景下,用Handler建立MessageQueue的机制管理线程操作更加条理。

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. RXJava
  3. Android(安卓)AysncTask 从源码角度简单理解它的使用限制原因
  4. 2019-04-01
  5. Android学习笔记两篇关于线程更新UI的方法的文章
  6. android looper,handler,messagequeue,message
  7. android(NDK+JNI)---JNI全面解析
  8. Android异步任务简单使用
  9. 【Android】如何在线更新Android(安卓)SDK Manager里的各种工具

随机推荐

  1. android顶部控件被输入法顶上去的解决办
  2. androidstudio解决Internal error please
  3. 让程序(服务)开机运行
  4. Android之DatePicker和TimePicker实现以
  5. Android(安卓)国际化和屏幕适配
  6. Android(安卓)Studio——private Handler
  7. android圆形图片显示ImageView超简单控件
  8. android之反射创建一个实例:构造方法带参
  9. Android使用wheelView实现简单类似ios Pi
  10. Android(安卓)Gradle 更新到 3.4.1 问题