Handler使用技巧

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就会发生泄漏,最终超出可使用内存,有造成内存溢出的危险。

-------分隔线------------

5 补充

Handler 可以直接post 里面是个Runnable,这里实际上没有创建新的线程,会在handler所在线程执行,内部直接调用run方法(不是直接开启线程),所以不要传递耗时操作。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值