Service和IntentService 的区别

it2023-01-04  92

区别

Service

不是运行在独立的线程,所以不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。

IntentService

① 可用于执行后台耗时的任务,任务执行后会自动停止。

② 具有高优先级,适合高优先级的后台任务,且不容易被系统杀死。

③ 可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandleIntent()回调方法中执行。

IntentService的使用

//新建一个类继承IntentService,并实现下面两个方法 public class MyIntentService extends IntentService { public MyIntentService(String name) { super(name); } @Override protected void onHandleIntent(@Nullable Intent intent) { //在这个方法做自己想做的事情 } }

源码分析

为什么IntentService可用于执行后台耗时的任务,任务执行后会自动停止

IntentService继承与Service,我们来看IntentService的onCreate()方法

@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(); //获取这个子线程的Looper mServiceLooper = thread.getLooper(); //新建一个Handler,把子线程的Looper传进去 //所以这个Handler在子线程运行 mServiceHandler = new ServiceHandler(mServiceLooper); }

那么这个Handler是什么时候发送消息的呢,我们来看IntentService的onStart方法

@Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; //原来这个Handler在onCreate创建,onStart发送消息 mServiceHandler.sendMessage(msg); }

我们再来看ServiceHandler的源码

private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { //Handler收到消息后,回调我们重写的onHandleIntent方法 //执行我们自定义的逻辑 onHandleIntent((Intent)msg.obj); //执行完逻辑,调用stopSelf方法自动停止 stopSelf(msg.arg1); } }

为什么IntentService具有高优先级

刚刚我们注意到,IntentService的onCreate()方法里创建了一个子线程 HandlerThread

@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); }

我们点进去HandlerThread 里面看,发现HandlerThread的构造函数里赋值了一个优先级

public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } /** * Standard priority of application threads. * Use with {@link #setThreadPriority(int)} and * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal * {@link java.lang.Thread} class. */ public static final int THREAD_PRIORITY_DEFAULT = 0;

这个优先级挺高的,所以很难被系统回收

为什么IntentService可以多次启动,每个耗时操作都会以工作队列的方式在onHandleIntent()回调方法中执行。

同样看IntentService的onCreate方法,我们注意到新建了一个Handler

@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(); //新建一个Handler mServiceHandler = new ServiceHandler(mServiceLooper); }

onStart()的时候发送消息

@Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; //这个Handler在onCreate创建,onStart发送消息 mServiceHandler.sendMessage(msg); }

多次启动IntentService 的时候,因为IntentService继承Service,所以onCreate方法执行了一次,onStart方法执行了多次。从而创建了一个Handler,发送了多次消息,这些消息以工作队列的方式在Handler里排队执行。

享学课堂

最新回复(0)