多线程详解——IntentService工作原理(源码详解)
目录
一、概述
二、应用
三、源码分析
四、Demo源码下载
一、概述
IntentService
是 Service
组件类的一个扩展,继承自Service,用于按需处理异步请求(以 Intent
的形式表达),避免IntentService中耗时操作造成主线程ANR,所以IntentService内部创建单独的工作线程HandleThread。客户端通过调用 android.content.Context#startService(Intent)
方法发送请求;服务会在需要时被启动,使用一个工作线程依次处理每个 Intent
,并在没有更多工作要处理时自行停止。
这种“工作队列处理器”模式通常用于将任务从应用程序的主线程中获取出来。IntentService
类的存在就是为了简化这种模式并处理其机制。要使用它,你需要扩展 IntentService
并实现 onHandleIntent(Intent)
方法。IntentService
会接收 Intent
,启动一个工作线程,并在适当的时候停止服务。
所有请求都在单个工作线程上处理——只要有请求,线程就会工作。(并且不会阻塞应用程序的主循环),但一次只能处理一个请求。
从Android 8.0版本开始,系统对后台任务的执行施加了更严格的限制,而IntentService作为一种处理后台任务的服务,也受到了这些限制的影响。因此,开发者在开发需要执行后台任务的应用时,可能需要考虑使用其他更适合当前Android系统限制的方法或工具。这里提到的androidx.work.WorkManager就是谷歌推荐的一种替代方案,它提供了更灵活、更强大的后台任务管理能力。
二、应用
开发步骤
- 自定义IntentService类
- 在清单文件中声明IntentService
- 创建组件启动IntentService
demo演示源码请见:章节四、源码下载
三、源码分析
@Deprecated
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
@UnsupportedAppUsage
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
//handler属于工作线程,处理操作运行在工作线程
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//在工作线程中处理intent
onHandleIntent((Intent)msg.obj);
//处理完毕后,自动关闭IntentService
stopSelf(msg.arg1);
}
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name 用于命名工作线程,方便debug
*/
public IntentService(String name) {
super();
mName = name;
}
@Override
public void onCreate() {
super.onCreate();
//创建工作线程
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//创建工作线程队列
mServiceLooper = thread.getLooper();
//创建工作线程Handler对象
mServiceHandler = new ServiceHandler(mServiceLooper);
}
/*接收intent,并通过onStart方法将intent发送到工作线程去处理*/
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);//发送intent给工作线程
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
//获取intent发给工作线程去处理
mServiceHandler.sendMessage(msg);
}
/**
* 此方法运行在工作线程去处理请求。一次只能处理一个intent请求,但处理过程独立于其他应用逻辑。因此,如果这段代码执行时间较长,它会阻塞对同一个 IntentService的其他请求,但不会阻塞其他任何事情。当所有的请求都被处理完以后,IntentService自动停止,不用主动调用stopSelf方法。
*
* @param intent 通过startService传递过来的Intent.如果服务在其进程结束后正在重新启动,则此值可能为null;有关详细信息,请参阅android.app.Service#onStartCommand
*/
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}