常用汇总Android应用开发那些事

Android 进阶之 Handler 消息机制

2019-04-02  本文已影响4人  Kevin_小飞象

众所周知,在 Android 中,非 UI 线程中是不能更新 UI 的,如果在子线程中做 UI 相关操作,可能会出现程序崩溃。一般的做法是,创建一个 Message 对象,Handler 发送该 message,然后在 Handler 的 handleMessage() 方法中做 UI 相关操作,这样就成功实现了子线程切换到主线程。

概念

核心类方法介绍:


method

流程

流程图

Handler.sendMessage()发送消息时,会通过MessageQueue.enqueueMessage()向MessageQueue中添加一条消息;
通过Looper.loop()开启循环后,不断轮询调用MessageQueue.next();
调用目标Handler.dispatchMessage()去传递消息,目标Handler收到消息后调用Handler.handlerMessage()处理消息。

特别注意:
线程(Thread)、循环器(Looper)、处理者(Handler)之间的对应关系如下:

使用

  1. 使用 Handler.sendMessage()
public class MainActivity extends AppCompatActivity {
    private Button mButton;

    private TextView mTextView;

    // 步骤1:在主线程中 通过匿名内部类 创建Handler类对象
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            // 步骤5:根据不同线程发送过来的消息,执行不同的UI操作
            if (msg.what == 1){
                mTextView.setText("执行了线程的UI操作");
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = findViewById(R.id.textView);
        mButton = findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 步骤2:创建所需的消息对象
                        Message msg = Message.obtain();
                        msg.what = 1; // 消息标识
                        msg.obj = "A"; // 消息内存存放

                        // 步骤3:在工作线程中 通过Handler发送消息到消息队列中
                        mHandler.sendMessage(msg);
                    }
                }.start(); // 步骤4:开启工作线程(同时启动了Handler)

            }
        });
    }
}
  1. 使用 Handler.post()
public class MainActivity extends AppCompatActivity {
    private Button mButton;
    private TextView mTextView;
    private Handler mHandler = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = findViewById(R.id.textView);
        mButton = findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mTextView.setText("执行了子线程的UI操作");
                            }
                        });
                    }
                }.start(); 
            }
        });
    }
}
上一篇下一篇

猜你喜欢

热点阅读