Handler使用技巧

版权声明:本文为博主原创文章,转载希望能注明出处,感谢。 https://blog.csdn.net/u010126792/article/details/83746552

1Handler 如何初始化

handler一般是使用方式是在主线程Handler handler = new Handler();初始化Handler,然后就可以愉快的使用了,此时的handler可以用于更新ui线程,在handleMessage中进行的操作相当于在ui线程。如果不是在ui线程初始化,这种初始化方式会报错。
Handler handler = new Handler(Looper.getMainLooper()); 可以更新ui。

2 Handler一定要在主线程实例化吗?

尝试在子线程中初始化handler是无法使用的,会报下面的错误:

 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
        at android.os.Handler.<init>(Handler.java:200)
        at android.os.Handler.<init>(Handler.java:114)
        at com.example.hpuzz.myapplication.MainActivity$2.run(MainActivity.java:86)
        at java.lang.Thread.run(Thread.java:761)

如果要在子线程中使用,需要手动调用Looper.prepare();
Looper.loop();
然后就可以愉快的发送消息了,但此时是不能更新ui的。

3 new Handler()和new Handler(Looper.getMainLooper())的区别

Handler handler = new Handler()不带参数的这种初始化方式,会默认用当前线程的looper,如果需要刷新UI就需要在主线程下运行。

如果在其他线程,也要更新ui的话,要Handler handler = new Handler(Looper.getMainLooper());这种最终的消息处理是在UI线程中。

在其他线程Handler handler = new Handler();之前需要Looper.prepare(); Handler handler = new Handler();Looper.loop();
或者Handler handler = new Handler(Looper.getMainLooper());

4 Handler 内存泄漏

 private MyHandler mHandler;

    static class MyHandler extends Handler
    {
        WeakReference<TaskCenterActivity> mWeakReference;
        public MyHandler(TaskCenterActivity activity)
        {
            mWeakReference=new WeakReference<TaskCenterActivity>(activity);
        }
        @Override
        public void handleMessage(Message msg)
        {
            final TaskCenterActivity activity=mWeakReference.get();
            if(activity!=null && msg.what == 1)
            {
               if (activity.mAwardGetDialog != null){
                   activity.mAwardGetDialog.dismiss();
               }
            }
        }
    }

内存泄漏原因:
内部类默认持有外部类的引用,如果handler发送延迟消息,此时关闭activity,由于延迟消息,线程执行还没有结束,都会造成Activity无法销毁,从而造成内存泄漏。

Handler发送的Message会被发送的MessageQueue里面,当消息Message有延迟处理时,会留在MessageQueue里面,而Message是持有mHandler的引用,Handler又是通过匿名内部类的形式创建的,会默认持有外部类Activity的引用。既然有引用存在,垃圾回收就无法回收这个activity,所以每次打开activity然后关闭,activity就会发生泄漏,最终超出可使用内存,有造成内存溢出的危险。

猜你喜欢

转载自blog.csdn.net/u010126792/article/details/83746552