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)