Handler消息传递机制学习

一:为什么要使用Handler ?

当在Android应用中执行耗时操作时,为了避免主线程(UI线程)拥塞,通常会新开一个非主线程去执行耗时任务,当耗时任务执行完并需要根据执行的结果去更新主线程中的UI组件时,如果在非主线程中直接更新UI很可能会导致线程安全问题,所以Android规定必须在UI线程中去更新组件,那么就要将非主线程中的结果发送到UI线程,而Handler就是起到将非UI线程中的数据发送到UI线程中去的作用,UI线程通过Handler的handleMessage()方法获取Handler发送过来的数据,并根据这些数据在UI线程中更新UI。


从上面可以看到Handler的作用为:

1.  在非UI线程中发送消息(消息中可以包含数据)。

2.  在UI线程中去获取、处理消息。

Handler工作流程:Handler先将消息(Message)发送到Looper管理的消息队列(MessageQueue),然后Handler在MessageQueue获取、处理Message。 Handler消息传递是一个自己发号命令然后自己去获取并执行的机制。


在子线程使用Handler必须自己创建Looper对象(通过Looper.prepare()创建),发送消息后使用Looper.loop启动Looper,Looper是用来管理消息队列的。主线程中因为系统已经初始化了一个Looper对象,所以不需要程序员去创建了,直接使用Handler即可

下满是Handler的使用例子,加深理解:

public class MainActivity extends AppCompatActivity {
    private final String NUMSTR = "number";
    private TextView tv;
    private Handler handler = new Handler(){
        // 主线程从消息队列中获取消息并提取数据
        public void handleMessage(Message msg){
            if(msg.what == 0x123){
                int number = msg.getData().getInt(NUMSTR);
                //  更新UI
                tv.setText(number+"");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)findViewById(R.id.tv);
        MyThread thread = new MyThread();
        //  启动线程
        thread.start();
    }
    //  耗时任务子线程中执行
    class MyThread extends Thread{
        int number = 0;
        public void run(){

            while(true){
                try {
                    //  模拟耗时任务
                    Thread.sleep(3000);
                    number++;
                    Message message = Message.obtain();
                    message.what = 0x123;
                    Bundle bundle = new Bundle();
                    bundle.putInt(NUMSTR,number);
                    message.setData(bundle);
                    //  handler发送消息到主线程
                    handler.sendMessage(message);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}
因为是在主线程中使用Handler,所以并不需要创建和启动Looper。若在子线程中使用Handler就需要创建和启动Looper,示例代码如下:

public class MainActivity extends AppCompatActivity {
    private Handler handler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyThread thread = new MyThread();
        //  启动线程
        thread.start();
    }
    class MyThread extends Thread{
        public void run(){
            Looper.prepare();    //  Looper.prepare()和Looper.loop()包起来的是个循环体
               handler = new Handler(){
                // 主线程从消息队列中获取消息并提取数据
                public void handleMessage(Message msg){
                    if(msg.what == 0x123){
                        Toast.makeText(MainActivity.this, "Boom", Toast.LENGTH_SHORT).show();
                    }
                }
            };
            Looper.loop();  这句代码后的代码都不会执行
        }
    }
    public void click(View v){    // 一个按钮的点击事件
        handler.sendEmptyMessage(0x123);
    }
}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android handler机制是一种在Android中用于处理异步消息和线程通信的重要机制。其主要作用是将消息和任务抛到主线程的消息队列中,以便主线程按照一定的规则按照队列中的顺序处理这些消息和任务。 1. Handler的实例化:在Android中,创建一个Handler的实例可以通过以下两种方式实现: 直接实例化: 创建一个Hanlder对象,代码示例: Handler handler = new Handler(); 绑定Looper:在子线程中创建Handler的话,需要先通过以下代码获取Looper对象,然后再将其传入Handler的构造函数中: Looper looper = Looper.myLooper(); Handler handler = new Handler(looper); 2. Handler的使用:当一个线程需要将一个耗时的任务交给主线程去执行的时候,它可以使用Handler来完成。以下是Handler的常见用法示例: 使用Handler处理消息: Handler myHandler = new Handler() { public void handleMessage(Message msg) { //在这里处理消息 } }; Message msg = myHandler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putString("my_key", "my_string"); msg.setData(bundle); myHandler.sendMessage(msg); 使用Handler更新UI: Handler myHandler = new Handler() { public void handleMessage(Message msg) { //更新UI } }; myHandler.sendEmptyMessage(0); 3. Handler的原理:在Android系统中,所有的UI操作都必须在主线程上完成。这时,Handler就扮演了一个传递任务的中介角色。它把来自子线程的消息和任务封装成Message对象,最后以一定的顺序扔到主线程的消息队列中等待执行。主线程通过Looper不断地循环读取消息队列中的消息和任务,然后依次执行。这就是Handler机制的基本原理。 4. Handler配合其他机制使用:为了更好地发挥Handler的作用,还可与一些其他机制有效配合使用,例如:AsyncTask、MessageQueue等等。通过多种机制的相互配合,可以实现复杂的异步消息处理和并发控制,提升了Android应用程序的性能和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值