简介
创建子线程,使用 handler 和 message 更新 UI 界面
Android 定义并启动线程的方法
继承 Thread 类
class MyThread extends Thread {
@Override
public void run() {
//处理逻辑
}
}
//启动
new MyThread().start();
实现 Runnable 接口
class MyThread implements Runnable {
@Override
public void run() {
//处理逻辑
}
}
//启动
MyThread myThread = new MyThread();
new Thread(myThread).start();
使用匿名类实现 Runnable 接口
new Thread(new Runnable() {
@Override
public void run() {
//处理逻辑
}
}).start();
在子线程中更新 UI
使用 runOnUiThread
是一个异步消息处理机制的接口封装。
runOnUiThread(new Runnable() {
@Override
public void run() {
text.setText("Nice to meet you 111");
}
});
利用异步消息处理
public static final int UPDATE_TEXT = 1;
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
if(message.what == UPDATE_TEXT) {
text.setText("Nice to meet you");
}
return false;
}
});
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message);
}
}).start();
异步处理机制解析
Android 异步消息处理由四个部分组成:Message、Handler、MessageQueue 和 Looper。
Message
线程之间传递的信息,可携带少量的信息,用于在不同线程之间交换数据;
message 可以携带 what 的 int 数据,除此之外 arg1 和 arg2 也可以携带 int 数据,obj 携带一个 Object 对象。
Handler
用于发送和处理消息。发送消息使用 handler 的 sendMessage 方法;处理消息在 handleMessage 方法中。
MessageQueue
主要存放所有通过 Handler 发送的消息,这部分消息一直存在于消息队列中,等待被处理。
每个线程只有一个 MessageQueue 对象。
Looper
是 MessageQueue 的管家;
调用 Looper 的 loop 方法后,就会进入到一个无限循环当中,每当发现 MessageQueue 存在一条消息,就会将它取出来传递到 Handler 的 handleMessage 方法中。
每个线程中也只有一个 Looper 对象。
AsyncTask
Android 封装的异步消息处理从子线程切换到主线程。
class UpdateTextTask extends AsyncTask<Void, Integer, Boolean> {
//在后台任务开始执行之前调用,做界面上的初始化操作
@Override
protected void onPreExecute() {
text.setText("start");
}
//在子线程中运行,通过 return 返回结果,调用 publishProgress 方法更新 UI
@Override
protected Boolean doInBackground(Void... voids) {
int count = 0;
while(count != 20) {
publishProgress(++count);
Log.d(TAG, "doInBackground: " + count);
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
return true;
}
//publishProgress 调用最终会到这个函数里,在这里对 UI 进行操作。
@Override
protected void onProgressUpdate(Integer... values) {
Log.d(TAG, "onProgressUpdate() called with: values = [" + values[0] + "]");
text.setText(""+values[0]);
}
//当后台任务执行完毕并 return 返回是会被调用,可以进行 UI 操作。
@Override
protected void onPostExecute(Boolean aBoolean) {
text.setText("end");
}
}
项目源码下载
Github