前言
除了AsyncTask之外,Android还提供了其他的一些线程操作来方便开发者使用,接下来进行总结
一、HandlerThread:
HandlerThread是用来替代Thread的,本身HandlerThread就是继承Thread的,但是与Thread的区别在于,内部有一个Looper成员变量,通过Thread+Looper来实现,实际上就是HandlerThread封装了一个带有自己Looper的线程,可以方便的利用它来处理耗时任务,达到解决一个线程多个异步任务的问题。
使用案例:
public class HandlerThreadActivity1 extends Activity {
HandlerThread fetchThread = new HandlerThread("fetching_thread");
Handler fetchHandler;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_thread);
tv = (TextView) findViewById(R.id.tv);
//启动线程
fetchThread.start();
//通过fetchHandler发送的消息,会被fetchThread线程创建的轮询器拉取到
fetchHandler = new Handler(fetchThread.getLooper()){
@Override
public void handleMessage(Message msg) {
//模拟访问网络延迟
SystemClock.sleep(1000);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText("汇率:"+new Random().nextInt(10));
}
});
//循环执行
fetchHandler.sendEmptyMessage(1);
}
};
}
@Override
protected void onResume() {
super.onResume();
fetchHandler.sendEmptyMessage(1);
}
@Override
protected void onStop() {
super.onStop();
fetchThread.quit(); //取消
}
}
HandlerThread源码分析如下:
public class HandlerThread extends Thread {
int mPriority;//线程优先级
int mTid = -1;
Looper mLooper;//当前线程持有的looper对象
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() {
mTid = Process.myTid();
Looper.prepare(); //创建Looper和messageQueue,将looper设置到ThreadLocal中
synchronized (this) {
mLooper = Looper.myLooper();//获取到looper对象
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();//开启子线程的消息循环
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
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;
}
public int getThreadId() {
return mTid;
}
重点看getLooper方法,首先会调用isAlive()方法测试线程是否还活着,如果不是,则直接返回null。接着会进入一个同步代码块,当线程还存活着且成员变量mLooper为null时,会执行wait操作,等待run方法中的notifyAll(),由此可知,只要之前我们的HandlerThread被启动了,这个方法会一直阻塞直至mLooper初始化完成,最后将初始化完成的mLooper返回出去。
通常情况下,HandlerThread启动后,会通过getLooper()方法取出Looper对象并将其作为Handler的初始化参数。此时,getLooper()方法是运行在主线程的,而Looper对象的初始化是位于子线程(HandlerThread)的run方法中的,getLooper()方法中的 wait()与run方法中的notifyAll()共同协作,实现了两个线程之间的同步。
总结:
1、HandlerThread本质上是一个Thread对象,只不过其内部帮我们创建了该线程的Looper和MessageQueue;
2、通过HandlerThread我们不但可以实现UI线程与子线程的通信同样也可以实现子线程与子线程之间的通信;
3、HandlerThread在不需要使用的时候需要手动的回收掉;
二、IntentService
IntentService的本质是Service+HandlerThread+Intent,它是IntentService的子类,可以提高子线程的优先级以及减轻主线程的压力,IntentService可以用来处理耗时操作,因为内部是利用HandlerThread来进行处理的。IntentService内部会创建一个HandlerThread,onHandleIntent在HandlerThread线程中执行
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper; //获取当前线程的looper
private volatile ServiceHandler mServiceHandler;
private String mName; //IntentService名称
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
//可以看到IntentService里封装的就是HandlerThread的实现过程
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
总结:
1、启动IntentService类型的Service后,系统通过ServiceHandler将携带的Intent消息放入由HandlerThread线程生成的Looper的消息队列中,Looper依次处理队列中的消息并通过dispatchMessage将消息交给ServiceHandler的Handler来具体执行(其实就是Handler的用法,和我们在Activity中创建Handler并在handleMessage中更新ui的用法一样,只不过这里的handleMessage是在HandlerThread这样的后台线程而不是ui线程中执行的)
2、调用子类的onHandleIntent方法(用来执行费时操作),结束后关闭Service 总之,这种机制通常用于希望按顺序执行(串行)而非并发(并行)执行的费时操作,
其中每个任务执行完毕的时间是未知的的应用场景。如果希望在任务结束后通知前台可以通过sendBroadCast的方式发送广播。
三、Loader机制
关于Loader机制,目前自己研究的还不是很深,建议可以看这篇博客:
http://blog.csdn.net/sk719887916/article/details/51540610