Handler

 

Android Handler实现原理

下面介绍最本质的多线程:hanlder和message机制:

为何需要多线程:

在日常应用中,我们通常需要处理一些“后台,用户不可见”的操作,例如说,我们需要下载一个音乐,要是你的应用必须等用户下载完成之后才可以进行别的操作,那肯定让用户非常的不爽。这时候,我们通常的做法是,让这些操作去后台执行,然后等后台执行完毕之后,再给用户弹出相应的提示信息。这时候,我们就需要使用多线程机制,然后通过创建一个新的线程来执行这些操作。

明白了,实现需求,我们就准备着手实现了。但是,经过进一步的了解,我们悲剧的发现,android中的线程机制是,只能在UI线程中和用户进行交互。当我们创建了一个新线程,执行了一些后台操作,执行完成之后,我们想要给用户弹出对话框以确认,但是却悲剧的发现,我们根本无法返回UI主线程了。

(说明:何为UI线程:UI线程就是你当前看到的这些交互界面所属的线程)。

这时候,我们如果想要实现这些功能,我们就需要一个android为我们提供的handler和message机制。

先讲解下编程机制:

我们通常在UI线程中创建一个handler,handler相当于一个处理器,它主要负责处理和绑定到该handler的线程中的message。每一个handler都必须关联一个looper,并且两者是一一对应的,注意,这点很重要哦!此外,looper负责从其内部的messageQueue中拿出一个个的message给handler进行处理。因为我们这里handler是在UI线程中实现的,所以经过这么一个handler、message机制,我们就可以回到UI线程中了。

何为handler:处理后台进程返回数据的工作人员。

何为message:后台进程返回的数据,里面可以存储bundle等数据格式

何为messageQueue:是线程对应looper的一部分,负责存储从后台进程中抛回的和当前handler绑定的message,是一个队列。

何为looper:looper相当于一个messageQueue的管理人员,它会不停的循环的遍历队列,然后将符合条件的message一个个的拿出来交给handler进行处理。

注意,handler是在UI线程中声明的,如果我们直接用类似代码执行一个线程的话,实际上并没有创建一个新的线程,因为handler已经跟默认的UI线程中的looper绑定了。

如果有兴趣的话,可以去看下Handler的默认空构造函数便知道原因了,里面直接绑定了当前UI线程的looper。

下面给出一个比较简单,并且实用的实例。

源码打印?
[java]  view plain copy
  1. package cn.com.src;    
  2.      
  3. import cn.com.chenzheng_java.utils.R;    
  4. import android.app.Activity;    
  5. import android.os.Bundle;    
  6. import android.os.Handler;    
  7. import android.os.HandlerThread;    
  8. import android.os.Looper;    
  9. import android.os.Message;    
  10. import android.util.Log;    
  11. import android.view.View;    
  12. import android.view.View.OnClickListener;    
  13. import android.widget.Button;    
  14.      
  15.    
  16. public class HanlderMessageTest extends Activity implements OnClickListener{    
  17.  Button button ;    
  18.  MyHandler handler ;    
  19.      
  20.  @Override    
  21.  protected void onCreate(Bundle savedInstanceState) {    
  22.  super.onCreate(savedInstanceState);    
  23.  setContentView(R.layout.main);    
  24.  button = (Button) this.findViewById(R.id.button1);    
  25.  button.setOnClickListener(this);    
  26.      
  27.      
  28.      
  29.  }    
  30.      
  31.  // 声明自己的handler    
  32.  private class MyHandler extends Handler{    
  33.      
  34.  public MyHandler() {    
  35.  super();    
  36.  }    
  37.      
  38.  public MyHandler(Looper looper){    
  39.  super(looper);    
  40.  }    
  41.      
  42.  // 处理具体的message,该方法由父类中进行继承.    
  43.  @Override    
  44.  public void handleMessage(Message msg) {    
  45.  int whatNumber = msg.what;    
  46.  Bundle bundle = (Bundle)msg.obj;    
  47.  Log.i("what", whatNumber+"");    
  48.  Log.i("名称", bundle.getString("name"));    
  49.  Log.i("性别", bundle.getString("sex"));    
  50.  Log.i("年龄", bundle.getString("age"));    
  51.  super.handleMessage(msg);    
  52.  }    
  53.  }    
  54.     
  55.  // 我自定义的任务,一般都会实现Runnable    
  56.  private class MyThread implements Runnable {    
  57.      
  58.  @Override    
  59.  public void run() {    
  60.      
  61.  try {    
  62.  Thread.sleep(6000);    
  63.  Message message = Message.obtain(handler);    
  64.  message.what = 10 ;    
  65.  Bundle bundle = new Bundle();    
  66.  bundle.putString("name""chenzheng");    
  67.  bundle.putString("sex""纯爷们");    
  68.  bundle.putString("age""生卒年不详");    
  69.  message.obj = bundle ;    
  70.  Log.i("通知""开始发message了哦");    
  71.  Log.i("通知thread_id:"""+Thread.currentThread().getId());    
  72.  message.sendToTarget();    
  73.  } catch (Exception e) {    
  74.  Log.i("通知""线程sleep时出错了!");    
  75.  e.printStackTrace();    
  76.  }    
  77.  }    
  78.  }    
  79.      
  80.  @Override    
  81.  public void onClick(View v) {    
  82.  Log.i("通知thread_id:"""+Thread.currentThread().getId());    
  83.      
  84.  // 创建一个包含Looper的线程,这里如果没有HandlerThread的调用,会直接将后边的MyThread放到UI线程队列    
  85.  HandlerThread myHandlerThread = new HandlerThread("chenzheng_java");    
  86.  // 启动新线程    
  87.  myHandlerThread.start();    
  88.  // 将handler绑定到新线程    
  89.  handler = new MyHandler(myHandlerThread.getLooper());    
  90.  // 在新线程中执行任务     
  91.  handler.post(new MyThread());    
  92.  }    
  93. }    

你可能感兴趣的:(Handler)