IntentService是继承Service的抽象类,所以IntentService的实现类需要重写onHandleIntent()方法。
内部:HandlerThread + Handler
HandlerThread
它是android提供的一个方便、便捷的类,用于快速创建一个带有Looper的线程。Looper可以用来创建Handler实例。注意:start()仍然必须被调用。
private void initHandlerThread(){
//创建HandlerThread实例
mHandlerThread = new HandlerThread("handler_thread");
//开始运行线程
mHandlerThread.start();
//获取HandlerThread线程中的Looper
Looper loop = mHandlerThread.getLooper();
//创建Handler与该线程绑定
mSubThreadHandler = new Handler(loop){};
}
看看IntentService的源码:
package android.app;
import android.annotation.WorkerThread;
import android.annotation.Nullable;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
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);
}
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public IntentService(String name) {
super();
mName = name;
}
/**
* Sets intent redelivery preferences. Usually called from the constructor
*/
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
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);
}
/**
* You should not override this method for your IntentService. Instead,
*/
@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();
}
/**
* Unless you provide binding for your service, you don't need to implement this
*/
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
/**
*/
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
从源码可以看出,在执行onCreate方法时会创建一个HandlerThread对象,并启动线程。紧接着创建ServiceHandler对象, ServiceHandler继承自Handler,用来处理消息。ServiceHandler将获取HandlerThread的Looper就可以开始工作了。
每启动一次onStart方法,就会把消息 和 数据 发给 mServiceHandler,相当于发送了一个Message 给 HandlerThread的消息队列。mServiceHandler会把 数据 传给 onHandleIntent方法, onHandleIntent是个抽象方法,需要在IntentService子类实现,每次onStart之后都会调用onHandleIntent方法去处理。处理完毕后,会调用stopSelf通知HandlerThread已经处理完毕,HandlerThread继续观察消息队列,如果还有未执行的message则继续执行,否则结束。
启动IntentService为什么不需要新建线程?
IntentService内部的HandlerThread继承自Thread,内部封装了Looper,在这里新建线程并启动,所以启动IntentService不需要新建线程。
为什么不建议通过 bindService 方法启动 IntentService?
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
IntentService源码中的onBind方法默认返回 null;不适合使用bindService启动。当然,如果执意要使用 bindService方法启动 IntentService,可能是想通过 Binder 或 Messenger 使IntentService 和 Activity可以通信, 这样的情况下 onHandleIntent不会被回调,相当于是在使用Service而不是IntentService。
为什么多次启动 IntentService 会顺序执行事件,停止服务后,后续的事件得不到执行?(也可以说IntentService中的操作不能被打断)
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
IntentService中使用Handler、Looper、MessageQueue机制把消息发送到线程中去执行, 所以多次启动 IntentService不会重新创建新的服务 和 新的 线程,只是把消息 加入消息队列中等待执行, 而如果服务停止,会清除消息队列中的消息----mServiceLooper.quit();,后续的事件得不到执行。
IntentService特点:
1)IntentService是继承自Service并处理异步请求的类, 在其内部创建了一个独立的工作线程来处理所有通过onStartCommand传递给服务的intent;
2)创建了一个工作队列,来逐个发送intent 给 onHandleIntent处理;
3)当任务执行完以后, IntentService自动停止,因为内部调用了stopSelf方法,所以不需要我们手动结束;
4)onBind方法默认返回null
注:如果启动 IntentService多次,那么每一个耗时操作会以工作队列的方式在 IntentService 的onHandleIntent 回调中执行,依次去执行, 使用串行的方式,执行完自动结束。
Service
Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,不建议在Service中编写耗时操作,否则会引起ANR,为了解决这样的问题,引入了IntentService。
本文深入解析了Android中的IntentService,一种用于处理异步请求的服务组件。它内部利用HandlerThread和Handler机制,确保所有Intent以串行方式处理,避免了主线程阻塞。文章详细介绍了IntentService的启动流程、消息队列机制及为何适合处理耗时操作。
205

被折叠的 条评论
为什么被折叠?



