| 知乎专栏 |
// 实例对象,参数为线程名字
HandlerThread handlerThread = new HandlerThread("handlerThread");
// 启动线程
handlerThread.start();
// 参数为 HandlerThread 内部的一个 looper
Handler handler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
HandlerThread 与 Thread 有什么不同?
// HandlerThread 相当于下面代码
new Thread () {
@Override
public void run() {
Looper.prepare();
Hnadler handler = new Handler();
Looper.loop();
}
}
mHanderThread = new HandlerThread(TAG);
mHanderThread.start();
mHandler = new Handler(mHanderThread.getLooper());
mHandler.post(new Runnable() {
@Override
public void run() {
}
});
// 步骤1:创建HandlerThread实例对象
// 传入参数 = 线程名字,作用 = 标记该线程
HandlerThread mHandlerThread = new HandlerThread("handlerThread");
// 步骤2:启动线程
mHandlerThread.start();
// 步骤3:创建工作线程Handler & 复写handleMessage()
// 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
// 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
Handler workHandler = new Handler( mHandlerThread.getLooper() ) {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case DownloadThread.TYPE_START:
Log.e(TAG, "TYPE_START");
break;
case DownloadThread.TYPE_FINISHED:
Log.e(TAG, "TYPE_FINISHED");
break;
default:
break;
}
return true;
}
});
// 步骤4:使用工作线程Handler向工作线程的消息队列发送消息
// 在工作线程中,当消息循环时取出对应消息 & 在工作线程执行相关操作
// a. 定义要发送的消息
Message msg = Message.obtain();
msg.what = 2; //消息的标识
msg.obj = "B"; // 消息的存放
// b. 通过Handler发送消息到其绑定的消息队列
workHandler.sendMessage(msg);
// 步骤5:结束线程,即停止线程的消息循环
mHandlerThread.quit();
public class MainActivity extends AppCompatActivity {
Handler mainHandler,workHandler;
HandlerThread mHandlerThread;
TextView text;
Button button1,button2,button3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 显示文本
text = (TextView) findViewById(R.id.text1);
// 创建与主线程关联的Handler
mainHandler = new Handler();
/**
* 步骤1:创建HandlerThread实例对象
* 传入参数 = 线程名字,作用 = 标记该线程
*/
mHandlerThread = new HandlerThread("handlerThread");
/**
* 步骤2:启动线程
*/
mHandlerThread.start();
/**
* 步骤3:创建工作线程Handler & 复写handleMessage()
* 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
* 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
*/
workHandler = new Handler(mHandlerThread.getLooper()){
@Override
// 消息处理的操作
public void handleMessage(Message msg)
{
//设置了两种消息处理操作,通过msg来进行识别
switch(msg.what){
// 消息1
case 1:
try {
//延时操作
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 通过主线程Handler.post方法进行在主线程的UI更新操作
mainHandler.post(new Runnable() {
@Override
public void run () {
text.setText("我爱学习");
}
});
break;
// 消息2
case 2:
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mainHandler.post(new Runnable() {
@Override
public void run () {
text.setText("我不喜欢学习");
}
});
break;
default:
break;
}
}
};
/**
* 步骤4:使用工作线程Handler向工作线程的消息队列发送消息
* 在工作线程中,当消息循环时取出对应消息 & 在工作线程执行相关操作
*/
// 点击Button1
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 通过sendMessage()发送
// a. 定义要发送的消息
Message msg = Message.obtain();
msg.what = 1; //消息的标识
msg.obj = "A"; // 消息的存放
// b. 通过Handler发送消息到其绑定的消息队列
workHandler.sendMessage(msg);
}
});
// 点击Button2
button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 通过sendMessage()发送
// a. 定义要发送的消息
Message msg = Message.obtain();
msg.what = 2; //消息的标识
msg.obj = "B"; // 消息的存放
// b. 通过Handler发送消息到其绑定的消息队列
workHandler.sendMessage(msg);
}
});
// 点击Button3
// 作用:退出消息循环
button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandlerThread.quit();
}
});
}
}
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
// 获取 HandlerThread 的 Looper 并创建 Handler
Handler handler = new Handler(handlerThread.getLooper());
// 获取线程名称
String threadName = handlerThread.getName(); // "MyHandlerThread"
HandlerThread handerThread = new HandlerThread(TAG);
handerThread.start();
Handler handler = new Handler(handerThread.getLooper());
handler.post(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10000);
Log.d(TAG, "handerThread 1 " + handerThread.getThreadId());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
handler.post(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
Log.d(TAG, "handerThread 2 " + handerThread.getThreadId());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
handler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG, "handerThread 3 " + handerThread.getThreadId());
}
});
handler.post(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Log.d(TAG, "handerThread 4 " + handerThread.getThreadId());
}
});
Token 用来标识线程,通过 Token取消任务
// 发送带 Token 的延时任务 handler.postDelayed(runnable, token, delayMillis); // 取消所有关联该 Token 的任务 handler.removeCallbacksAndMessages(token);
使用 null 作为 Token:
handler.postDelayed(task, null, 2000); // 不推荐 handler.removeCallbacksAndMessages(null); // 会取消所有未指定 Token 的任务
混用 Token 和非 Token 方法:
handler.postDelayed(task1, 2000); // 未指定 Token handler.postDelayed(task2, TOKEN, 2000); // 指定 Token handler.removeCallbacksAndMessages(TOKEN); // 只取消 task2,不影响 task1