Android异步消息处理机制(一):简单使用

本文介绍了Android中的异步消息处理机制,重点讲解了Handler的基本用法及其在不同线程间的消息传递过程,并提供了实例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天发博客说要看源码写博客,今天终于要开张了;第一个专题是Android异步消息处理机制,虽然平时经常用到Handler,用法也比较简单,但是看完源码之后,发现里面还是有很多知识点的^_^

1.概述

Handler在平常开发中经常使用到,用来在不同组件(这里的组件不是Android里的组件,可以理解为代码块,类,线程,进程都可以)之间进行消息传递;

本专题会分以下几篇(暂定两篇)来详细描述:

Android异步消息处理机制(一):简单使用;

Android异步消息处理机制():源码分析;

源码是Android4.0.3版本的;

2.用法

在平常使用中,接触到的类有Message,Handler,Looper,在使用中最重要的类是Handler;关于Hanlder的介绍,在源码注释中

有这么一段描述

    There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the 
future; and (2) to enqueue an action to be performed on a different thread than your own.                                                                                                                                               
	大概意思就是Handler有两个用处,一是序列化Message和Runnable对象,以便在将来的某个时间点进行处理;二是在不同线程之间发送消息;
其实在某些跨进程场景下,也可以使用Handler(Handler里Messager对象就是用来跨进程消息接收) 
	下面将介绍前两种用法,第三种(跨进程消息传递)暂不介绍,在后续的Binder专题中会专门介绍;                                                                                                                                                                                                                                       

  1)序列化Message和Runnable

public class TestActivity extends Activity implements View.OnClickListener {

    private static final int MSG_CLICK_ONE = 1;
    private static final int MSG_CLICK_TWO = 2;

    private MyHandler mHandler = new MyHandler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        findViewById(R.id.tv_click_one).setOnClickListener(this);
        findViewById(R.id.tv_click_two).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_click_one:
                mHandler.sendEmptyMessage(MSG_CLICK_ONE);
                break;
            case R.id.tv_click_two:
                mHandler.sendEmptyMessage(MSG_CLICK_TWO);
                break;
        }
    }

    private static class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_CLICK_ONE:
                    Log.e("Test", "click one");
                    break;
                case MSG_CLICK_TWO:
                    Log.e("Test", "click two");
                    break;
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    }

}

上面就是最简单的代码块之间的消息传递,上面提到Message和Runnable的序列化,其实Runnable最终也是生成Message对象进入消息队列的;

2)线程之间消息传递

public class TestActivity extends Activity implements View.OnClickListener {

    private static final int MSG_CLICK = 1;

    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        findViewById(R.id.tv_click).setOnClickListener(this);
        MyThread thread = new MyThread();
        thread.start();
        mHandler = thread.getHandler();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_click:
                mHandler.sendEmptyMessage(MSG_CLICK);
                break;
            default:
                break;
        }
    }

    private static class MyThread extends Thread {
        private MyHandler mHandler;
        @Override
        public void run() {
            //初始化子线程的Looper和MessageQueue
            Looper.prepare();
            mHandler = new MyHandler();
            //消息队列进入循环执行
            Looper.loop();
        }
        
        public Handler getHandler() {
            return mHandler;
        }
    }

    private static class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_CLICK:
                    Log.e("Test", "click");
                    break;
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    }

}
需要注意的是,主线程(UI线程)在启动的时候会自己生成Looper和MessageQ,但是子线程是没有,所以在子线程执行的时候要先初始化Looper和MessageQueue对象,之后才能使用消息队列进行消息接收和处理;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值