Handler机制(详解)

为了避免ANR,我们会通常把 耗时操作放在子线程里面去执行,因为子线程不能更新UI,所以当子线程需要更新的UI的时候就需要借助到安卓的消息机制,也就是Handler机制了。

注意:在安卓的世界里面,当 子线程 在执行耗时操作的时候,不是说你的主线程就阻塞在那里等待子线程的完成——也不是调用 Thread.wait()或是Thread.sleep()。安卓采取的方法是,主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程。以这种方式设计你的应用程序,将能保证你的主线程保持对输入的响应性并能避免由于5秒输入事件的超时引发的ANR对话框。

一个程序的运行,就是一个进程的在执行,一个进程里面可以拥有很多个线程。

  • 主线程:也叫UI线程,或称ActivityThread,用于运行四大组件和处理他们用户的交互。 ActivityThread管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),在Android系统中,在默认情况下,一个应用程序内的各个组件(如Activity、BroadcastReceiver、Service)都会在同一个进程(Process)里执行,且由此进程的主线程负责执行。
    ActivityThread既要处理Activity组件的UI事件,又要处理Service后台服务工作,通常会忙不过来。为了解决此问题,主线程可以创建多个子线程来处理后台服务工作,而本身专心处理UI画面的事件。
  • 子线程: 用于执行耗时操作,比如 I/O操作和网络请求等。(安卓3.0以后要求耗访问网络必须在子线程种执行)更新UI的工作必须交给主线程,子线程在安卓里是不允许更新UI的。 
  • Handler的简单使用
    既然子线程不能更改界面,那么我们现在就借助Handler让我们更改一下界面:
    主要步骤是这样子的:
    1、new出来一个Handler对象,复写handleMessage方法
    2、在需要执行更新UI的地方 sendEmptyMessage 或者 sendMessage
    3、在handleMessage里面的switch里面case不同的常量执行相关操作
  • 代码
  • import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.widget.TextView;
    
    
    public class MainActivity extends Activity {
    
    
        private TextView mTv;
        private Handler mHandler;
        private static final int MSG_UPDATE_TEXT = 0x2001; // 更新文本  方式一用的常量
        private static final int MSG_UPDATE_WAY_TWO = 0x2002;  // 更新文本 方式二用的常量
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mHandler=new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what){
                        case MSG_UPDATE_TEXT:
                            mTv.setText("让Handler更改界面");
                            break;
    
                        case MSG_UPDATE_WAY_TWO:
                            mTv.setText("让Handler更改界面方式二");
                            break;
                    }
                }
            };
    
    
    
            mTv= (TextView) findViewById(R.id.mTv);
            mTv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d("Test", "点击文字");
    
                    // 方式一和方式二可以达到相同的效果,就是更改界面
    
                    // 方式一
                    //mHandler.sendEmptyMessage(MSG_UPDATE_TEXT);
    
                    // 方式二
                    Message msg =Message.obtain();
                    msg.what= MSG_UPDATE_WAY_TWO;
                    mHandler.sendMessage(msg);
    
    
                }
            });
    
        }
    
    /*    private void sonThreadUpdateUi(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    mTv.setText("子线程想要更改界面");
                }
            }).start();
        }*/
    
    }

    Handler的工作机制简单来说是这样的

    Handler的工作机制简单来说是这样的

    1. Message 消息 ,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
    2. Message Queue 消息队列 ,用来存放通过Handler发布的消息,按照先进先出执行。
    3. Handler Handler是Message的主要处理者 ,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
    4. Looper 循环器 ,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
    5. 线程 UI thread 通常就是main thread ,而Android启动程序时会替它建立一个Message Queue。每一个线程里含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接 收Looper所送出的消息。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值