Android系统为多线程提供的几种方案以及各自应用场景
1、异步任务 AsyncTask
AsyncTask是切换UI线程和工作线程的一种快捷方式,默认是一种线性队列执行方式。
场景:是那种需要立即执行的、生命周期短的需求。
比如:界面上面有一个Button,点击立即从后台获取信息这种需求.
缺点:不易使用和内存泄露
doInBackground(...){
if (isCancelled)
...
}
需要在代码里面加判断来取消异步任务。
还有一个令很多人头疼的内存泄露问题,因为一般AsyncTask都是Activity/Fragment的内部类,很容易导致AsyncTask和Activity生命周期不一致导致内存泄露。
2、HandlerThread
HandlerThread是Looper+MessageQueue+Handler组合的一个简单实现。
场景:需要执行长时间任务的需求
比如:打开手机相机预览图片需求,如果用AsyncTask不能把后台拿到的结果快速反应到UI上,HandlerThread可以通过runOnUIThread方法快速把拿到的图片反应到UI上。再比如可以用这个开发一个网络图片加载库等等。
3、ThreadPool线程池
ThreadPool是并发处理的有效方案,把任务分成小任务,然后分发到各个不同的线程上面。
场景:大量、并发的请求任务
比如:网络请求库,图片加载库等大量并发请求的场景,Glide底层网络请求就是用的线程池
Glide createGlide() {
if (sourceService == null) {
final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
//初始化线程池
sourceService = new FifoPriorityThreadPoolExecutor(cores);
}
......
}
缺点:消耗大量的CPU,因为每开一个线程耗费64K的内存,使用不当就会导致性能严重下降。
4、IntentService
IntentService是Service+HandlerThread,因为Service是执行在UI线程的,如果要在Service执行耗时任务也是需要开启线程执行的,这里android为我们提供了一个方便的方式就是Intentservice。
-----------------------------------------分割线--------------------------------------------
Handler:面试中大量问到了Handler、Looper、MessageQueue,以前不明白直到现在看了各个库的源码发现,底层都是用他们的机制实现的!
RxJava:
static class HandlerWorker extends Worker {
private final Handler handler;
private final RxAndroidSchedulersHook hook;
private volatile boolean unsubscribed;
HandlerWorker(Handler handler) {
this.handler = handler;
this.hook = RxAndroidPlugins.getInstance().getSchedulersHook();
}
@Override
public void unsubscribe() {
unsubscribed = true;
handler.removeCallbacksAndMessages(this /* token */);
}
@Override
public boolean isUnsubscribed() {
return unsubscribed;
}
@Override
public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
if (unsubscribed) {
return Subscriptions.unsubscribed();
}
action = hook.onSchedule(action);
ScheduledAction scheduledAction = new ScheduledAction(action, handler);
Message message = Message.obtain(handler, scheduledAction);
message.obj = this; // Used as token for unsubscription operation.
handler.sendMessageDelayed(message, unit.toMillis(delayTime));
if (unsubscribed) {
handler.removeCallbacks(scheduledAction);
return Subscriptions.unsubscribed();
}
return scheduledAction;
}
@Override
public Subscription schedule(final Action0 action) {
return schedule(action, 0, TimeUnit.MILLISECONDS);
}
}
Retrofit:
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
多多少少都能看到Handler的身影!!!