Android Handler 消息机制

2019-07-08  本文已影响0人  xulj100

1、先来了解下下面的几个重要的组件:

image.png

2、在子线程中创建Handler:
方法1:在new Handler()前后加上 Looper.prepare()和 Looper.loop()

//子线程创建handler,需要创建looper
  new Thread(new Runnable() {
     @Override
      public void run() {
          Looper.prepare();
          @SuppressLint("HandlerLeak")
          Handler handler = new Handler() {
           @Override
           public void handleMessage(Message msg) {
             super.handleMessage(msg);
                    }
                };
              Looper.loop();
            }
        }).start();  

方法二:传入主线程的Looper来实现

 //将主线程的looper传进来
new Thread(new Runnable() {
  @Override
  public void run() {
  Handler handler = new Handler(Looper.getMainLooper()) {
  @Override
  public void handleMessage(Message msg) {
    super.handleMessage(msg);
            }
        };
    }
 }).start();

3、handler之内存泄漏:
造成泄露原因:

4、如何避免内存泄露:

 private static class ActivityHandler extends Handler {
        private final WeakReference<AsyncActivity> mActivity;

        public ActivityHandler(AsyncActivity activity) {
            this.mActivity = new WeakReference(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            if (this.mActivity != null) {
                AsyncActivity activity = this.mActivity.get();
                if (activity != null && !activity.isFinishing()) {
                    activity.handleMessage(msg);
                }
            }
        }
    }

    public void handleMessage(Message msg) {
    }

5、Looper能创建多个实例嘛?能自己创建Looper实例嘛?
Looper只能创建一个实例,可以自己调用Looper.prepare()方法创建实例。
先来看Looper的prepare()方法,调用多次prepare方法创建实例,会抛出异常。

  public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

ThreadLocal类的特性:ThreadLocal是线程内部的数据存储类,当使用ThreadLocal维护变量的时候,它会为每个使用该变量的线程提供一个独立的变量副本,这个变量副本是该线程独有,不受其他线程影响。
Looper的主要作用是与当前线程形成一种绑定的关系,同时创建一个MessageQueue,这样保证一个线程只能持有一个Looper和MessageQueue,同时Looper使得MessageQueue循环起来。

6、handler,asyncTask有什么区别?
Android的AsyncTask比Handler更轻量级一些(只是代码上轻量一些,而实际上要比handler更耗资源),适用于简单的异步处理。
AsyncTask的重写方法:

使用AsyncTask类,以下是几条必须遵守的准则:

AsyncTask优缺点
优点:简单,快捷, 过程可控。
缺点:在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来,最大并发数不超过5。
Handler优缺点:
优点:结构清晰,功能定义明确,对于多个后台任务时,简单,清晰。
缺点:在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)。

上一篇 下一篇

猜你喜欢

热点阅读