android HandlerThread 循环线程
工作线程串行执行
能够确保线程持续存活并且可以不断的从任务队列中获取任务并进行执行
能够帮助实现队列任务的管理,不仅仅能够把任务插入到队列的头部,尾部,还可以按照一定的时间延迟来确保任务从队列中能够来得及被取消掉
使用 Intent,Message,Runnable 作为任务的载体在不同的线程之间进行传递。
使用
//1.创建实例对象
HandlerThread handlerThread = new HandlerThread("handlerThread");
//2.启动HandlerThread线程,构建完一个循环线程
handlerThread.start();
//3.构建循环消息处理机制 Handler
Handler subHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
//实现自己的消息处理
return true;
}
});
HandlerThread
public class HandlerThread extends Thread {
//线程优先级
int mPriority;
//当前线程id
int mTid = -1;
//当前线程持有的Looper对象
Looper mLooper;
//构造方法
public HandlerThread(String name) {
//调用父类默认的方法创建线程
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
//带优先级参数的构造方法
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
//获得当前线程的id
mTid = Process.myTid();
//准备循环条件
Looper.prepare();
//持有锁机制来获得当前线程的Looper对象
synchronized (this) {
mLooper = Looper.myLooper();
//发出通知,当前线程已经创建mLooper对象成功,这里主要是通知getLooper方法中的wait
notifyAll();
}
//设置当前线程的优先级
Process.setThreadPriority(mPriority);
//该方法实现体是空的,子类可以实现该方法,作用就是在线程循环之前做一些准备工作,当然子类也可以不实现。
onLooperPrepared();
//启动loop
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
//如果线程不是存活的,则直接返回null
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
//如果线程已经启动,但是Looper还未创建的话,就等待,知道Looper创建成功
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
//安全退出循环
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
}
Looper
- 与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue
- loop()方法,不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理
- prepare()
public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(true)); } - Looper()
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mRun = true; mThread = Thread.currentThread(); } - loop()
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(" Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); if (logging != null) { logging.println("Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycle(); } }
Handler
其他线程(发送) --->> 绑定线程(执行)
- new Handler(); new Handler(callback);
自动绑定到所在线程 UI线程定义Handler过调用Looper.myLooper()获取当前线程绑定的Looper对象,然后将该Looper对象保存到名为mLooper的成员字段中。
//uiHandler在主线程中创建时自动绑定主线程 private Handler uiHandler = new Handler(); //使用sendMessage(Message)方式 Handler uiHandler2 = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: { //拿到数据,完成主界面更新 String data = (String) msg.obj; textView.setText(data); break; } default: break; } } }; // Handler uiHandler3 = new Handler(new Handler.Callback(){ @Override public boolean handleMessage(Message msg) { //实现自己的消息处理 return true; } }); - new Handler(looper); new Handler(looper,callback)
- post(Runnable) -->Runnable.run()
无须实现handleMessage(Message msg)post(Runnable);//提交计划任务马上执行 postAtTime(Runnable, long);//提交计划任务在未来的时间点执行 postDelayed(Runnable, long);//提交计划任务延时Nms执行 - sendMessage(Message) -->handleMessage(Message)
sendEmptyMessage(int);//发送一个空的消息 sendMessage(Message);//发送消息,消息中可以携带参数 sendMessageAtTime(Message, long);//未来某一时间点发送消息 sendMessageDelayed(Message, long);//延时Nms发送消息 //最终都调用了sendMessageAtTime(Message, long) public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } //注意下面这行代码 return enqueueMessage(queue, msg, uptimeMillis); } - handleMessage(Message msg)
Handler机制扩展
其他线程(发送) --->> UI线程(执行)
- Activity.runOnUiThread(Runnable)
- View.post(Runnable)
Message
api- Message msg =new Message(); //不建议
Message msg =Message.obtain(myHandler);
Message msg =myHandler.obtainMessage(); - public int arg1;
public int arg2;
public Object obj;
public int what; //用户自定义的消息代码 - public void setData (Bundle data)
public Bundle getData ()