Android消息机制Handler用法总结

 更新时间:2021年11月26日 17:10:53   作者:天若子  
这篇文章介绍了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 {
 
  /**
   * Instances of static inner classes do not hold an implicit
   * reference to their outer class.
   */
  private static class MyHandler extends Handler {
    private final WeakReference<SampleActivity> mActivity;
 
    public MyHandler(SampleActivity activity) {
      mActivity = new WeakReference<SampleActivity>(activity);
    }
 
    @Override
    public void handleMessage(Message msg) {
      SampleActivity activity = mActivity.get();
      if (activity != null) {
        // ...
      }
    }
  }
 
 // MyHandler
 private final MyHandler mHandler = new MyHandler(this);
 
  /**
   * Instances of anonymous classes do not hold an implicit
   * reference to their outer class when they are "static".
   */
  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);
    }
}

以上所述是小编给大家介绍的Android消息机制Handler用法总结,希望对大家有所帮助。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • Android开发中总结的Adapter工具类【附完整源码下载】

    Android开发中总结的Adapter工具类【附完整源码下载】

    这篇文章主要介绍了Android开发中总结的Adapter工具类,简单说明了Adapter的功能,并结合实例形式分析了Adapter工具类的相关使用方法,并附带完整源码供读者下载参考,需要的朋友可以参考下
    2017-11-11
  • Android Service启动流程刨析

    Android Service启动流程刨析

    这几天分析了一下的启动过程,于是乎,今天写一下Service是如何启动的; 给我的感觉是这些启动过程并不复杂,千万不要被一坨一坨的代码吓住了,虽然弯弯绕绕不少,重载函数一个接着一个,就向走迷宫一样,但只要抓住主线阅读,很快就能找到出口
    2022-08-08
  • 深入浅析Android手机卫士保存密码时进行md5加密

    深入浅析Android手机卫士保存密码时进行md5加密

    一般的手机没有root权限,进不去data/data目录,当手机刷机了后,拥有root权限,就可以进入data/data目录,查看我们保存的密码文件,因此我们需要对存入的密码进行MD5加密,接下来通过本文给大家介绍Android手机卫士保存密码时进行md5加密,需要的朋友一起学习吧
    2016-04-04
  • Android利用Espresso进行UI自动化测试的方法详解

    Android利用Espresso进行UI自动化测试的方法详解

    因为我是搞android开发的,所以被分到了自动化测试小组,所以了解了一些UI自动化测试。下面这篇文章主要给大家介绍了关于Android利用Espresso进行UI自动化测试的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-12-12
  • AndroidStudio项目打包成jar的简单方法

    AndroidStudio项目打包成jar的简单方法

    JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件,在eclipse中我们知道如何将一个项目导出为jar包,供其它项目使用呢?下面通过本文给大家介绍ndroidStudio项目打包成jar的简单方法,需要的朋友参考下吧
    2017-11-11
  • Android使用美团多渠道打包方案详解

    Android使用美团多渠道打包方案详解

    这篇文章主要介绍了Android使用美团多渠道打包方案详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • Android Studio项目中导入开源库的方法

    Android Studio项目中导入开源库的方法

    这篇文章主要介绍了Android Studio项目中导入开源库的方法,即使用第三方库、第三广场框架的方法,需要的朋友可以参考下
    2015-06-06
  • Android 深入探究自定义view之事件的分发机制与处理详解

    Android 深入探究自定义view之事件的分发机制与处理详解

    对于安卓程序员来说,自定义view简直不要太重要,毕竟有很多功能,譬如圆形头像这些,用单纯的原生非常难以实现,而用自定义view,简直分分钟
    2021-11-11
  • Android中Handler与Message的简单实例

    Android中Handler与Message的简单实例

    这篇文章主要介绍了Android中Handler与Message的简单实例的相关资料,这里提供实例来说明线程Handler与message 的结合使用,需要的朋友可以参考下
    2017-08-08
  • Android studio有关侧滑的实现代码

    Android studio有关侧滑的实现代码

    这篇文章主要介绍了Android studio有关侧滑的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06

最新评论