需求:实现一个线程,里面可以提交若干任务,并确保这些任务都是在该线程中执行,同时可以控制启动(线程start并且可以添加任务)和停止(线程stop不可添加其他任务)。
代码解释:调用requestStart()后可以execute(runnable)多个任务,调用requestStop()后execute(runnable)不执行,同时保证每个任务都是在当前线程中执行。
/*
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package com.rockchip.tutk.utils;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.util.concurrent.Executor;
/**
* Looper based executor class.
*/
public class LooperExecutor extends Thread implements Executor {
private static final String TAG = "LooperExecutor";
// Object used to signal that looper thread has started and Handler instance
// associated with looper thread has been allocated.
private final Object looperStartedEvent = new Object();
private Handler handler = null;
private boolean running = false;
private long threadId;
@Override
public void run() {
// 在当前线程中创建Handler绑定本线程,此handler内部是一个死循环,不停地轮询消息(导致线程不死)
Looper.prepare();
synchronized (looperStartedEvent) {
Log.d(TAG, "Looper thread started.");
handler = new Handler();
threadId = Thread.currentThread().getId();
looperStartedEvent.notify();
}
Looper.loop();
}
// 保证本线程已经启动并实例化了Handler对象,此方法阻塞的时间等于线程的就绪态到运行态的时间
public synchronized void requestStart() {
if (running) {
return;
}
running = true;
handler = null;
start();// 开启线程,当前线程为就绪态(等待cpu的执行即run方法的执行)
// Wait for Hander allocation. 我线程没启动完毕你老老实实地阻塞在这里吧!
synchronized (looperStartedEvent) {
while (handler == null) {
try {
looperStartedEvent.wait();
} catch (InterruptedException e) {
Log.e(TAG, "Can not start looper thread");
running = false;
}
}
}
}
public synchronized void requestStop() {
if (!running) {
return;
}
running = false;
handler.post(new Runnable() {
@Override
public void run() {
// 停掉handler所在线程中的消息轮询(结束线程)
Looper.myLooper().quit();
Log.d(TAG, "Looper thread finished.");
}
});
}
// Checks if current thread is a looper thread.
public boolean checkOnLooperThread() {
return (Thread.currentThread().getId() == threadId);
}
@Override
public synchronized void execute(final Runnable runnable) {
if (!running) {
Log.w(TAG, "Running looper executor without calling requestStart()");
return;
}
// 确保runnable的运行总是在创建此handler的线程中执行即
if (Thread.currentThread().getId() == threadId) {
runnable.run();
} else {
// 假设创建此handler的线程为A而有另外的线程B,C中使用了本类实例execute方法,这时就得把当前的runable发送给线程A执行
handler.post(runnable);
}
}
}