handle机制原理

  java代码
  1. package com.example.handlertest;

  2.   import android.os.Bundle;
  3.   import android.os.Handler;
  4.   import android.os.Looper;
  5.   import android.os.Message;
  6.   import android.app.Activity;
  7.   import android.view.Menu;
  8.   import android.view.View;
  9.   import android.view.View.OnClickListener;
  10.   import android.widget.Button;
  11.   /**
  12.   * 通过一个demo来讲解下几种Handler处理的情况
  13.   *
  14.   *
  15.   *
  16.   * 为了引入Handler消息机制,我们必须先知道“同步”和“异步”通信的差别
  17.   *
  18.   * “同步”通信: 比如 我打电话给小明,跟小明进行对话,我必须等到和小明结束通话之后,才能再拨打其他人的电话
  19.   * (同步就是发送一个请求之后,什么事都不做,一直等到结果返回后才继续做下面的事情)
  20.   *
  21.   * "异步"通信: 比如 我给几个同学发送E-mail邮件,全部发送过去之后,不需要在这边等他们回复, 
  22. 我还可以去做别的事情,他们回复的时候,邮箱系统会通知我
  23.   * (异步就是发出请求之后,这个请求完成之后,通过状态,通知或者回调等方式来通知调用者处理的结果)
  24.   *
  25.   *
  26.   * Handler机制的产生原因: 一个应用程序开启之后,首先会开启一个UI线程(主线程),顾名思义是用来管理界面中UI控件的,
  27.   * 并对事件进行分发,比如一个Button的点击事件,android把事件分发到对应的Button上,来响应用户操作
  28.   * 但由于用户有可能需要做一些耗时的操作(下载文件),但是android如果5秒钟界面没反应的话,就会提示
  29.   * 用户关闭应用程序了,所以这时候需要把这些耗时的操作放在 子线程 中处理,子线程处理完成之后再去更新
  30.   * UI线程中的界面,而Android的UI线程又是不安全的,这样意味着子线程中无法直接更新UI线程的界面,
  31.   * 因此Android中设计了Handler来解决这个问题!
  32.   *
  33.   * 解决方法: Handler运行在UI线程中,它与子线程可通过Message对象来传递数据,这时候,handler就承担了接收子线程
  34.   * 传来的Message对象的责任,从而配合UI线程更新UI。
  35.   *
  36.   *
  37.   * Handler消息机制:
  38.   *
  39.   *
  40.   * 1.handler存取消息的原理:
  41.   *
  42.   * Handler允许发送并处理Message消息,Message消息通过主线程的MessageQueue消息队列相关联的Message和
  43.   * Runnable对象进行存取,当创建一个新的handler时(在主线程中创建),handler就属于当前主线程,主线程的
  44.   * MessageQueue也同步创建,Handler会绑定到该主线程/消息队列中,这样,handler就可以通过主线程的消息队列
  45.   * 发送和接收Message消息对象了
  46.   *
  47.   *
  48.   * 2.Handler消息处理机制的几种情况[下面用代码来说明这几种情况]: 2.1 button1: 主线程中做Handler 2.2 
  49. button2:
  50.   * 子线程中做Handler 2.3 button3: 把主线程创建的Handler传递给其他线程完成消息处理 2.4 button4:
  51.   * 在其他线程中更新UI线程界面,它抛出异常,我们看看哈~!
  52.   *
  53.   *
  54.   *
  55.   * 
  56. 发送Message不会阻塞线程(异步),而接收消息处理会阻塞线程[当Handler处理完一个Message对象后才会接着去取下一个消息进行处理](同步)
  57.   *
  58.   *
  59.   * 2013年09月11日23:37:08
  60.   *
  61.   * @author xiaoyaomeng
  62.   *
  63.   */
  64.   public class MainActivity extends Activity implements OnClickListener {
  65.   HandlerDemo myHandlerDemo = null;// 该对象用于主线程中创建handler
  66.   Button button1 = null;
  67.   Button button2 = null;
  68.   Button button3 = null;
  69.   Button button4 = null;
  70.   @Override
  71.   protected void onCreate(Bundle savedInstanceState) {
  72.   super.onCreate(savedInstanceState);
  73.   setContentView(R.layout.activity_main);
  74.   button1 = (Button) findViewById(R.id.button1);
  75.   button2 = (Button) findViewById(R.id.button2);
  76.   button3 = (Button) findViewById(R.id.button3);
  77.   button4 = (Button) findViewById(R.id.button4);
  78.   button1.setOnClickListener(this);
  79.   button2.setOnClickListener(this);
  80.   button3.setOnClickListener(this);
  81.   button4.setOnClickListener(this);
  82.   }
  83.   @Override
  84.   public boolean onCreateOptionsMenu(Menu menu) {
  85.   // Inflate the menu; this adds items to the action bar if it is 
  86. present.
  87.   getMenuInflater().inflate(R.menu.main, menu);
  88.   return true;
  89.   }
  90.   @Override
  91.   public void onClick(View v) {
  92.   // TODO Auto-generated method stub
  93.   handlerDealMessage(v.getId());
  94.   }
  95.   private void handlerDealMessage(int id) {
  96.   // TODO Auto-generated method stub
  97.   switch (id) {
  98.   case R.id.button1: {
  99.   // 主线程中创建Handler实例
  100.   myHandlerDemo = new HandlerDemo();
  101.   Message message = myHandlerDemo.obtainMessage(1,
  102.   (Object) ("Hello,My name is Handler1~~"));
  103.   message.sendToTarget();// Handler发送消息,会对应发送到这个和这个Handler绑定的UI线程做处理
  104.   }
  105.   break;
  106.   case R.id.button2: {
  107.   MyThread myThread = new MyThread();
  108.   myThread.start();
  109.   }
  110.   break;
  111.   case R.id.button3: {
  112.   myHandlerDemo = new HandlerDemo();
  113.   OtherThread otherThread = new OtherThread(myHandlerDemo);
  114.   otherThread.start();
  115.   }
  116.   break;
  117.   case R.id.button4: {
  118.   errorHandlerThread errorHandlerThread = new errorHandlerThread(
  119.   button4);
  120.   errorHandlerThread.start();
  121.   }
  122.   break;
  123.   default:
  124.   break;
  125.   }
  126.   }
  127.   /*
  128.   * MyThread 是内部类,子线程
  129.   */
  130.   private class MyThread extends Thread {
  131.   @Override
  132.   public void run() {
  133.   // TODO Auto-generated method stub
  134.   super.run();
  135.   // 1.error: 只能在UI线程中采用不带Looper对象创建Handler对象,所以此处会报异常
  136.   // myHandlerDemo = new HandlerDemo();
  137.   // 2.error: Looper.myLooper获取的Looper是null,所以也会报异常
  138.   // myHandlerDemo = new HandlerDemo(Looper.myLooper());
  139.   // 
  140. 通过Looper.getMainLooper()可以得到父类的looper,所以可以成功创建handler对象并绑定MessageQueue
  141.   myHandlerDemo = new HandlerDemo(Looper.getMainLooper());
  142.   Message message = myHandlerDemo.obtainMessage(2,
  143.   (Object) ("Hello,My name is Handler2~~"));
  144.   message.sendToTarget();
  145.   }
  146.   }
  147.   private/**
  148.   * 创建一个Handler
  149.   *
  150.   * @author xiaoyaomeng
  151.   *
  152.   */
  153.   class HandlerDemo extends Handler {
  154.   /* 在UI线程中创建handler时,可以直接调用这个构造函数 */
  155.   public HandlerDemo() {
  156.   super();
  157.   // TODO Auto-generated constructor stub
  158.   }
  159.   /* 在子线程中创建一个Handler需要用到这个构造函数,否则报错 */
  160.   public HandlerDemo(Looper looper) {
  161.   super(looper);
  162.   // TODO Auto-generated constructor stub
  163.   }
  164.   @Override
  165.   public void handleMessage(Message msg) {
  166.   // TODO Auto-generated method stub
  167.   super.handleMessage(msg);
  168.   switch (msg.what) {
  169.   case 1: {
  170.   button1.setText(msg.obj.toString());
  171.   }
  172.   break;
  173.   case 2: {
  174.   button2.setText(msg.obj.toString());
  175.   }
  176.   break;
  177.   case 3: {
  178.   button3.setText(msg.obj.toString());
  179.   }
  180.   break;
  181.   default:
  182.   break;
  183.   }
  184.   }
  185.   }
  186.   }
  187.   /**
  188.   *
  189.   * 其他线程的类,用来接收一个handler,并在线程中 用这个handler发送消息
  190.   *
  191.   * @author xiaoyaomeng
  192.   *
  193.   */
  194.   class OtherThread extends Thread {
  195.   private Handler mHandler;
  196.   public OtherThread(Handler handler) {
  197.   // TODO Auto-generated constructor stub
  198.   mHandler = handler;
  199.   }
  200.   @Override
  201.   public void run() {
  202.   // TODO Auto-generated method stub
  203.   super.run();
  204.   Message message = mHandler.obtainMessage(3,
  205.   (Object) ("Hello,My name is Handler3~~"));
  206.   message.sendToTarget();
  207.   }
  208.   }
  209.   /**
  210.   * 测试错误报错的线程
  211.   *
  212.   * @author xiaoyaomeng
  213.   *
  214.   */
  215.   class errorHandlerThread extends Thread {
  216.   Button button = null;
  217.   public errorHandlerThread(Button button) {
  218.   // TODO Auto-generated constructor stub
  219.   this.button = button;
  220.   }
  221.   @Override
  222.   public void run() {
  223.   // TODO Auto-generated method stub
  224.   super.run();
  225.   button.setText("hahahaha~~~");
  226.   }
  227.   }
<think>嗯,用户想了解Android中的Handler机制原理及实现。根据提供的引用资料,我需要整理出清晰的概念和实现步骤。首先,看看引用[1]提到的五个部分:Message、Handler、MessageQueue、Looper和ThreadLocal。这些是Handler机制的核心组件。 然后,引用[2]提到Handler的作用是切换任务到指定线程执行,特别是主线程中的操作都通过主线程的Handler处理。这说明Handler用于线程间通信,尤其是子线程向主线程发送消息。 引用[3]中的代码示例展示了如何在主线程创建Handler,并在子线程发送消息。这涉及到Looper.myLooper()获取主线程的Looper,然后处理消息。需要解释这些组件如何协作。 接下来,我需要分步骤解释原理。首先,消息循环(Looper)如何通过prepare()和loop()启动,以及MessageQueue如何存储消息。然后,Handler如何发送消息到队列,并由Looper分发处理。注意ThreadLocal的作用,确保每个线程有独立的Looper实例。 在实现部分,应该按照创建Handler的步骤来讲解,包括初始化Looper、创建Handler实例,以及发送和处理消息的流程。同时要提到主线程默认初始化Looper,而子线程需要手动调用Looper.prepare()和loop()。 可能用户的问题还包括为什么需要Handler,或者如何处理内存泄漏,但根据当前引用,重点在原理和基本实现。最后生成的相关问题要围绕主线程Looper、消息处理流程、ThreadLocal作用等,确保覆盖用户可能进一步想了解的内容。</think>### Handle机制原理及实现解析 #### 一、核心组件 Android的Handle机制由5个核心对象构成: 1. **Message**:消息载体,包含what、arg1/arg2、obj等字段 2. **Handler**:消息处理器,负责发送和处理消息 3. **MessageQueue**:消息队列(优先级队列),存储待处理消息[^1] 4. **Looper**:消息循环器,持续从队列提取消息 5. **ThreadLocal**:保证每个线程拥有独立的Looper实例 $$ \begin{aligned} &\text{Handler机制流程图} \\ &\text{Thread A} \xrightarrow{\text{sendMessage()}} \text{MessageQueue} \xrightarrow{\text{next()}} \text{Looper.loop()} \xrightarrow{\text{dispatch}} \text{Thread B} \end{aligned} $$ #### 二、实现原理 1. **消息循环建立** - 通过`Looper.prepare()`创建当前线程的Looper实例 - `Looper.loop()`启动无限循环,使用`MessageQueue.next()`阻塞获取消息 - 主线程默认已初始化MainLooper[^2] 2. **消息传递过程** ```java // Handler发送消息最终调用路径 Handler.sendMessageAtTime() → MessageQueue.enqueueMessage() → Looper.loop() → Message.target.dispatchMessage() ``` 3. **线程关联机制** - Handler创建时绑定当前线程的Looper - 通过ThreadLocal保证线程隔离性 - 消息处理始终在执行`loop()`的线程[^3] #### 三、标准实现步骤 1. **初始化Looper(子线程需要)** ```kotlin class WorkThread : Thread() { lateinit var handler: Handler override fun run() { Looper.prepare() // 创建消息队列 handler = object : Handler() { override fun handleMessage(msg: Message) { // 处理消息 } } Looper.loop() // 启动消息循环 } } ``` 2. **消息发送示例** ```kotlin // 主线程发送消息到子线程 workThread.handler.sendMessage( Message.obtain().apply { what = MSG_UPDATE_UI obj = "data" } ) ``` 3. **消息处理流程** ```mermaid graph LR A[Handler.sendMessage] --> B[MessageQueue.enqueue] B --> C[Looper.loop] C --> D[MessageQueue.next] D --> E[Handler.dispatchMessage] E --> F[handleMessage] ``` #### 四、关键特性说明 1. **线程切换本质**:通过消息队列实现跨线程任务调度 2. **延迟消息实现**:基于`epoll`机制的时间排序队列 3. **同步屏障**:通过`postSyncBarrier()`处理紧急消息 4. **内存泄漏**:Handler持有外部类引用时需使用WeakReference
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值