您现在的位置是:主页 > news > 谷歌云 阿里云 做网站/免费网站java源码大全
谷歌云 阿里云 做网站/免费网站java源码大全
admin2025/6/19 8:04:18【news】
简介谷歌云 阿里云 做网站,免费网站java源码大全,做网站的术语,wordpress ajax 插件一 、HandlerThread简介 从字面意思上看,它既与Handler有关系又与Thread有联系。确实如此,它继承自Thread,是一个线程类,同时又内嵌Looper对象。因此,用它开启的线程的内部可以直接创建一个Handler,并可以…
一 、HandlerThread简介
从字面意思上看,它既与Handler有关系又与Thread有联系。确实如此,它继承自Thread,是一个线程类,同时又内嵌Looper对象。因此,用它开启的线程的内部可以直接创建一个Handler,并可以与主线程交互。
关于Looper和Handler的协作请参考安卓学习笔记之android消息机制
二、源码分析
1、构造方法,用于设置线程名和初始化线程优先级。务必要通过start方法来开启线程
public HandlerThread(String name) {super(name);mPriority = Process.THREAD_PRIORITY_DEFAULT;
}/*** Constructs a HandlerThread.* @param name* @param priority The priority to run the thread at. The value supplied must be from */
public HandlerThread(String name, int priority) {super(name);mPriority = priority;
}
2、run方法,初始化Looper对象
可以看到HandlerThread内置了Looper消息循环。onLooperPrepared方法在Looper开始loop之前,做一些初始化或设置。普通Thread的run方法一般都做一些耗时操作,但在此run方法做的是创建Lopper并开启消息轮循,我们可以在线程的外部通过handler发消息让它做一些事情。注意,不要试图重写其run方法并做耗时操作!
@Override
public void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;
}/*** Call back method that can be explicitly overridden if needed to execute some* setup before Looper loops.*/
protected void onLooperPrepared() {
}
3、获取Looper对象,用于关联一个Handler。当线程启动但Looper没有创建完成时需等待。
/*** This method returns the Looper associated with this thread. If this thread not been started* or for any reason is isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper.*/
public Looper getLooper() {if (!isAlive()) {return null;}// If the thread has been started, wait until the looper has been created.synchronized (this) {while (isAlive() && mLooper == null) {try {wait();} catch (InterruptedException e) {}}}return mLooper;
}
4、 资源回收
由于run方法不会自动停止(Looper.loop()的原因),所以当我们不使用HandlerThread时,可以调用它的quit或quitSafely方法退出线程,否则线程资源得不到回收。
// 直接退出,不处理余留消息/*** Quits the handler thread's looper.* <p>* Causes the handler thread's looper to terminate without processing any* more messages in the message queue.*/public boolean quit() {Looper looper = getLooper();if (looper != null) {looper.quit();return true;}return false;
}//安全退出,等到所有在消息队列的消息被处理完成。
/*** Quits the handler thread's looper safely.* <p>* Causes the handler thread's looper to terminate as soon as all remaining messages* in the message queue that are already due to be delivered have been handled.*/
public boolean quitSafely() {Looper looper = getLooper();if (looper != null) {looper.quitSafely();return true;}return false;
}
三、简单案例
模拟一个下载任务,在HandlerThread线程中执行耗时操作,并向主线程发送消息以更新UI,当任务完成时,主线程会向子线程发送消息以停止子线程的消息轮循。
package com.yu.threadspool;import android.annotation.SuppressLint;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.os.SystemClock;import android.util.Log;import android.widget.TextView;public class HandlerThreadTest extends Activity {public static final int MSG_FROM_MAIN = 0; public static final int MSG_FROM_THREAD = 1;public static final int MSG_TASK_DONE = 2;public static final int MSG_QUIT = 3;HandlerThread handlerThread;Handler threadHandler; //子线程int count = 0;TextView tv; // 显示进度Handler mainHanlder = new Handler() { // 主线程handlerpublic void handleMessage(Message msg) {switch (msg.what) {case MSG_FROM_THREAD:tv.setText((String) msg.obj);break;case MSG_TASK_DONE:tv.setText("完成!");threadHandler.obtainMessage(MSG_QUIT).sendToTarget();break;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.handler_thread);tv = (TextView) findViewById(R.id.tv_text);initHandlerThread();// 做一些事情,在子线程threadHandler.post(new Runnable() {public void run() {Log.e("TAG", "thread:" + Thread.currentThread().getName());while (count < 100) {++count;Log.e("TAG", "count:" + count);SystemClock.sleep(200); // 模拟耗时Message msg = mainHanlder.obtainMessage(MSG_FROM_THREAD,String.valueOf(count));msg.sendToTarget(); // 向主线程发送消息,更新UI}// 发送任务完成消息mainHanlder.obtainMessage(MSG_TASK_DONE).sendToTarget();};});}/*** 初始化HandlerThread*/private void initHandlerThread() {handlerThread = new HandlerThread("HandlerThread#1");handlerThread.start(); // 务必要调用,且必须在关联Handler之前threadHandler = new Handler(handlerThread.getLooper())// 将threadHandler与handlerThread线程关联{@SuppressLint("NewApi") @Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == MSG_QUIT) {handlerThread.getLooper().quitSafely(); // 退出消息轮循,释放资源Log.e("TAG", Thread.currentThread().getName()+"退出");}}};}
}
执行结果
09-08 09:49:45.132: E/TAG(2162): thread:HandlerThread#1
09-08 09:49:45.132: E/TAG(2162): count:1
09-08 09:49:45.332: E/TAG(2162): count:2
09-08 09:49:45.532: E/TAG(2162): count:3
09-08 09:49:45.742: E/TAG(2162): count:4
09-08 09:49:45.942: E/TAG(2162): count:5... ... (省略部分)
09-08 09:50:04.332: E/TAG(2162): count:96
09-08 09:50:04.532: E/TAG(2162): count:97
09-08 09:50:04.742: E/TAG(2162): count:98
09-08 09:50:04.942: E/TAG(2162): count:99
09-08 09:50:05.142: E/TAG(2162): count:100
09-08 09:50:05.342: E/TAG(2162): HandlerThread#1退出