欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

异步消息处理(Message, Handler, MessageQueue, Looper)

程序员文章站 2022-07-14 20:02:31
...

AsyncTask 适用于单线程任务处理,多任务处理还是 Message/Handler 处理方便一些

主要使用方式:
1,创建子类继承自 Handler 类,覆盖 handleMessage(Message) 方法,switch Message 对象的 what(int 类型) 域等携带的信息,用于在 UI 线程中进行对应的操作;
2,new 一个 Handler 对象,并保存,之后发送 Message 对象会用到;
3,子线程中进行耗时操作,完成后 new 一个 Message 对象,设置 what, obj(可选)域;
4,使用 Handler 对象的 sendMessage(Message) 方法即可将 Message 发送给 Handler 对象。

这看起来像是回调,不过差异还是挺大的。主要的区别就是 Handler 对象的 sendMessage(Message) 方法只是通知 Handler 对象,之后 handlerMessage(Message) 会自动在 UI 线程中被调用,而直接调用对应方法则不会回到 UI 线程。

package club.seliote.demo;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

import java.util.Random;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private static final int MESSAGE_UPDATE_0 = 0;
    private static final int MESSAGE_UPDATE_1 = 1;
    private static final int MESSAGE_UPDATE_2 = 2;
    private static final int MESSAGE_UPDATE_3 = 3;

    private TextView mTextView;

    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_main);
        this.mTextView = (TextView) this.findViewById(R.id.text_view);
        /**
         * Step 2
         */
        this.mHandler = new DownloadHandler();
        this.download();
    }

    private void download() {
        for (int i = 0; i < 100; i++) {
            /**
             * Step 3
             */
            new Thread(() -> {
                try {
                    // 模拟下载
                    Thread.sleep((long) (Math.random() * 10000));
                }
                catch (InterruptedException interruptedException) {
                    Log.e(TAG, Thread.currentThread().getId() + " had interrupted!");
                    Message message = new Message();
                    message.what = 4;
                    message.obj = this.mTextView;
                    this.mHandler.sendMessage(message);
                    return;
                }
                Message message = new Message();
                message.what = new Random().nextInt(4);
                message.obj = this.mTextView;
                /**
                 * Step 4
                 */
                this.mHandler.sendMessage(message);
            }).start();
        }
    }

    /**
     * Step 1
     */
    private class DownloadHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // 判断具体的消息类型,进行相应处理
            switch (msg.what) {
                case MainActivity.MESSAGE_UPDATE_0:
                    // Object 类型参数可以用来传递要更新的对象
                    ((TextView)(msg.obj)).setText("000000");
                    ((TextView)(msg.obj)).setTextColor(MainActivity.this.getResources().getColor(R.color.red));
                    break;
                case MainActivity.MESSAGE_UPDATE_1:
                    ((TextView)(msg.obj)).setText("111111");
                    ((TextView)(msg.obj)).setTextColor(MainActivity.this.getResources().getColor(R.color.black));
                    break;
                case MainActivity.MESSAGE_UPDATE_2:
                    ((TextView)(msg.obj)).setText("222222");
                    ((TextView)(msg.obj)).setTextColor(MainActivity.this.getResources().getColor(R.color.blue));
                    break;
                case MainActivity.MESSAGE_UPDATE_3:
                    ((TextView)(msg.obj)).setText("333333");
                    ((TextView)(msg.obj)).setTextColor(MainActivity.this.getResources().getColor(R.color.grey));
                    break;
                default:
                    ((TextView)(msg.obj)).setText("-1-1-1-1-1-1");
                    ((TextView)(msg.obj)).setTextColor(MainActivity.this.getResources().getColor(R.color.colorAccent));
                    break;
            }
        }
    }
}