分享

Handler消息机制的一些原理(直接用code讲解)

 昵称17121610 2014-05-03
package com.example.handlertest; 
   
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Looper; 
import android.os.Message; 
import android.app.Activity; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
   
/**
 * 通过一个demo来讲解下几种Handler处理的情况
 
 
 
 * 为了引入Handler消息机制,我们必须先知道“同步”和“异步”通信的差别
 
 * “同步”通信: 比如 我打电话给小明,跟小明进行对话,我必须等到和小明结束通话之后,才能再拨打其他人的电话
 * (同步就是发送一个请求之后,什么事都不做,一直等到结果返回后才继续做下面的事情)
 
 * "异步"通信: 比如 我给几个同学发送E-mail邮件,全部发送过去之后,不需要在这边等他们回复, 我还可以去做别的事情,他们回复的时候,邮箱系统会通知我
 * (异步就是发出请求之后,这个请求完成之后,通过状态,通知或者回调等方式来通知调用者处理的结果)
 
 
 * Handler机制的产生原因: 一个应用程序开启之后,首先会开启一个UI线程(主线程),顾名思义是用来管理界面中UI控件的,
 * 并对事件进行分发,比如一个Button的点击事件,android把事件分发到对应的Button上,来响应用户操作
 * 但由于用户有可能需要做一些耗时的操作(下载文件),但是android如果5秒钟界面没反应的话,就会提示
 * 用户关闭应用程序了,所以这时候需要把这些耗时的操作放在 子线程 中处理,子线程处理完成之后再去更新
 * UI线程中的界面,而Android的UI线程又是不安全的,这样意味着子线程中无法直接更新UI线程的界面,
 * 因此Android中设计了Handler来解决这个问题!
 
 * 解决方法: Handler运行在UI线程中,它与子线程可通过Message对象来传递数据,这时候,handler就承担了接收子线程
 * 传来的Message对象的责任,从而配合UI线程更新UI。
 
 
 * Handler消息机制:
 
 
 * 1.handler存取消息的原理:
 
 * Handler允许发送并处理Message消息,Message消息通过主线程的MessageQueue消息队列相关联的Message和
 * Runnable对象进行存取,当创建一个新的handler时(在主线程中创建),handler就属于当前主线程,主线程的
 * MessageQueue也同步创建,Handler会绑定到该主线程/消息队列中,这样,handler就可以通过主线程的消息队列
 * 发送和接收Message消息对象了
 
 
 * 2.Handler消息处理机制的几种情况[下面用代码来说明这几种情况]: 2.1 button1: 主线程中做Handler 2.2 button2:
 * 子线程中做Handler 2.3 button3: 把主线程创建的Handler传递给其他线程完成消息处理 2.4 button4:
 * 在其他线程中更新UI线程界面,它抛出异常,我们看看哈~!
 
 
 
 * 发送Message不会阻塞线程(异步),而接收消息处理会阻塞线程[当Handler处理完一个Message对象后才会接着去取下一个消息进行处理](同步)
 
 
 * 2013年09月11日23:37:08
 
 * @author xiaoyaomeng
 
 */ 
   
public class MainActivity extends Activity implements OnClickListener { 
    HandlerDemo myHandlerDemo = null;// 该对象用于主线程中创建handler 
    Button button1 = null
    Button button2 = null
    Button button3 = null
    Button button4 = null
   
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
   
        button1 = (Button) findViewById(R.id.button1); 
        button2 = (Button) findViewById(R.id.button2); 
        button3 = (Button) findViewById(R.id.button3); 
        button4 = (Button) findViewById(R.id.button4); 
   
        button1.setOnClickListener(this); 
        button2.setOnClickListener(this); 
        button3.setOnClickListener(this); 
        button4.setOnClickListener(this); 
    
   
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
        // Inflate the menu; this adds items to the action bar if it is present. 
        getMenuInflater().inflate(R.menu.main, menu); 
        return true
    
   
    @Override 
    public void onClick(View v) { 
        // TODO Auto-generated method stub 
        handlerDealMessage(v.getId()); 
    
   
    private void handlerDealMessage(int id) { 
        // TODO Auto-generated method stub 
        switch (id) { 
        case R.id.button1: { 
            // 主线程中创建Handler实例 
            myHandlerDemo = new HandlerDemo(); 
            Message message = myHandlerDemo.obtainMessage(1
                    (Object) ("Hello,My name is Handler1~~")); 
            message.sendToTarget();// Handler发送消息,会对应发送到这个和这个Handler绑定的UI线程做处理 
        
            break
        case R.id.button2: { 
            MyThread myThread = new MyThread(); 
            myThread.start(); 
        
            break
        case R.id.button3: { 
            myHandlerDemo = new HandlerDemo(); 
            OtherThread otherThread = new OtherThread(myHandlerDemo); 
            otherThread.start(); 
        
            break
        case R.id.button4: { 
            errorHandlerThread errorHandlerThread = new errorHandlerThread( 
                    button4); 
            errorHandlerThread.start(); 
        
            break
        default
            break
        
    
   
    /*
     * MyThread 是内部类,子线程
     */ 
    private class MyThread extends Thread { 
        @Override 
        public void run() { 
            // TODO Auto-generated method stub 
            super.run(); 
   
            // 1.error: 只能在UI线程中采用不带Looper对象创建Handler对象,所以此处会报异常 
            // myHandlerDemo = new HandlerDemo(); 
   
            // 2.error: Looper.myLooper获取的Looper是null,所以也会报异常 
            // myHandlerDemo = new HandlerDemo(Looper.myLooper()); 
   
            // 通过Looper.getMainLooper()可以得到父类的looper,所以可以成功创建handler对象并绑定MessageQueue 
            myHandlerDemo = new HandlerDemo(Looper.getMainLooper()); 
            Message message = myHandlerDemo.obtainMessage(2
                    (Object) ("Hello,My name is Handler2~~")); 
            message.sendToTarget(); 
   
        
    
   
    private/**
             * 创建一个Handler
             
             * @author xiaoyaomeng
             *
             */ 
    class HandlerDemo extends Handler { 
        /* 在UI线程中创建handler时,可以直接调用这个构造函数 */ 
        public HandlerDemo() { 
            super(); 
            // TODO Auto-generated constructor stub 
        
   
        /* 在子线程中创建一个Handler需要用到这个构造函数,否则报错 */ 
        public HandlerDemo(Looper looper) { 
            super(looper); 
            // TODO Auto-generated constructor stub 
        
   
        @Override 
        public void handleMessage(Message msg) { 
            // TODO Auto-generated method stub 
            super.handleMessage(msg); 
   
            switch (msg.what) { 
            case 1: { 
                button1.setText(msg.obj.toString()); 
            
                break
            case 2: { 
                button2.setText(msg.obj.toString()); 
            
                break
            case 3: { 
                button3.setText(msg.obj.toString()); 
            
                break
            default
                break
   
            
   
        
    
   
/**
 
 * 其他线程的类,用来接收一个handler,并在线程中 用这个handler发送消息
 
 * @author xiaoyaomeng
 
 */ 
class OtherThread extends Thread { 
    private Handler mHandler; 
   
    public OtherThread(Handler handler) { 
        // TODO Auto-generated constructor stub 
   
        mHandler = handler; 
    
   
    @Override 
    public void run() { 
        // TODO Auto-generated method stub 
        super.run(); 
   
        Message message = mHandler.obtainMessage(3
                (Object) ("Hello,My name is Handler3~~")); 
        message.sendToTarget(); 
   
    
   
/**
 * 测试错误报错的线程
 
 * @author xiaoyaomeng
 
 */ 
class errorHandlerThread extends Thread { 
   
    Button button = null
   
    public errorHandlerThread(Button button) { 
        // TODO Auto-generated constructor stub 
        this.button = button; 
    
   
    @Override 
    public void run() { 
        // TODO Auto-generated method stub 
        super.run(); 
   
        button.setText("hahahaha~~~"); 
   
    
}  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多