栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android之Handler消息机制总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android之Handler消息机制总结

1.简述

Handler消息机制主要包括: MessageQueue、 Handler、 Looper、Message。

Message:需要传递的消息,可以传递数据;

MessageQueue:消息队列,但是它的内部实现并不是用的队列,而是通过单链表的数据结构来维护消息列表,因为单链表在插入和删除上比较有优势。主要功能是向消息池投递消息( MessageQueue.enqueueMessage)和取走消息池的消息( MessageQueue.next)。 

Handler:消息辅助类,主要功能是向消息池发送各种消息事件( Handler.sendMessage)和处理相应消息事件( Handler.handleMessage); 

Looper:消息控制器,不断循环执行( Looper.loop),从MessageQueue中读取消息,按分发机制将消息分发给目标处理者。

2.异步线程切换原理
class LooperThread extends Thread {
      public Handler mHandler;
 
      public void run() {
          Looper.prepare();
 
          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };
 
          Looper.loop();
      }
  }

每一个异步线程,都维护着唯一的一个Looper,每一个Looper会初始化(维护)一个MessageQueue,之后进入一个无限循环一直在读取MessageQueue中存储的消息,如果没有消息那就一直阻塞等待。
我们在实例化handler的过程中,会先得到当前所在线程的looper对象,之后得到与该looper对象相对应的消息队列,看源码Handler中持有Looper、MessageQueue。

    private static void handleCallback(Message message) {
        message.callback.run();
    }

    final Looper mLooper;
    final MessageQueue mQueue;
    final Callback mCallback;


当我们发送消息的时候,即handler.sendMessage或者handler.post,会将msg中的target赋值为handler自身,这就是实现message从一个线程到另外一个线程的传递的本质,之后加入到消息队列中。

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}

我们一般会重写handlerMessage方法处理消息,这将会在msg.target.disPatchMessage方法中被回调,从而实现了message从一个线程到另外一个线程的传递。

3.总结

1.Handler 的背后有 Looper、MessageQueue 支撑,Looper 负责消息分发,MessageQueue 负责消息管理;

2.在创建 Handler 之前一定需要先创建 Looper,Looper 有退出的功能,但是主线程的 Looper 不允许退出;

3.异步线程Looper,Looper.prepare()创建Looper,Looper.loop()开始轮询,需要自己调用 Looper.myLooper().quit()退出;

4.Runnable 被封装进了 Message,可以说是一个特殊的 Message;

5.Handler.handleMessage() 所在的线程是 Looper.loop() 方法被调用的线程;

6.Handler内存泄漏的原因

原因:MessageQueue持有Message,Message持有activity,delay多久,message就会持有activity多久。

解决方案:静态内部类、弱引用,最后不要忘记调用Handler.removeCallbacksAndMessages(null)清空所有消息。

public class SampleActivity extends Activity {

  
  private static class MyHandler extends Handler {
    private final WeakReference mActivity;

    public MyHandler(SampleActivity activity) {
      mActivity = new WeakReference(activity);
    }

    @Override
    public void handleMessage(Message msg) {
      SampleActivity activity = mActivity.get();
      if (activity != null) {
        // ...
      }
    }
  }

 // MyHandler
 private final MyHandler mHandler = new MyHandler(this);

  
  private static final Runnable sRunnable = new Runnable() {
      @Override
      public void run() {  }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Post a message and delay its execution for 10 minutes.
    mHandler.postDelayed(sRunnable, 1000 * 60 * 10);
    
    // Go back to the previous Activity.
    finish();
  }

  @Override
  protected void onDestroy() {
        super.onDestroy();
        //mHandler.removeCallbacksAndMessages(null);
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/600945.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号