首页 > 代码库 > Android多线程机制和Handler的使用

Android多线程机制和Handler的使用

参考教程: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的机制管理线程操作更加条理。

 

Android多线程机制和Handler的使用