In depth analysis of the differences between Service and IntentService in Android system

  • 2021-07-06 11:45:23
  • OfStack

Service in Android is used for background services, When the application is hung in the background, The concept of Service is introduced to ensure that some components of the application can still work. It should be emphasized that Service is not an independent process or an independent thread, and it depends on the main thread of the application. That is to say, it is not recommended to write time-consuming logic and operations in Service more often, otherwise it will cause ANR.

Then when the time-consuming logic we wrote has to be managed by service, we need to introduce IntentService. IntentService inherits Service, so it contains all the characteristics of Service, and of course it also contains the life cycle of service. Then, unlike service, IntentService has a thread inside when executing onCreate operation, so that you can perform your time-consuming operation.

service itself has two problems:

(1) service does not start a single process, and service is located in the same process as its application.

(2) service is not a special new thread, and should not handle time-consuming operations in service.

IntentService makes up for this one point well:

(1) IntentService creates a separate worker thread to process all intent requests.

(2) IntentService creates a separate worker thread to process the code for the onHandleIntent () method implementation.

(3) When all requests are processed, IntentService will stop automatically.

(4) Provides a default implementation for the OnBind () method of Service, which returns null.

(5) Provides a default implementation for the onStartCommand () method of service, which adds the request intent to the queue.

Therefore, the use of IntentService is to inherit IntentService and override onHandleIntent () method.

tips:
(1) Intentservice must also be declared in manifest.
(2) The constructor of the implementation class must implement the default constructor.

Here I need to explain the following methods, which may be clear to everyone, but in order to attract jade, I still want to mention one.

One method is provided in Service:


public int onStartCommand(Intent intent, int flags, int startId) { 
   onStart(intent, startId); 
   return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY; 
 } 

The specific meaning of this method is that when you need this service to start or call this servcie, this method will be called back first.

At the same time, IntentService provides such a method:


protected abstract void onHandleIntent(Intent intent); 

This is an abstract method, which means that the concrete implementation needs to be extended to subclasses.

Declaration of subclasses:


public class ChargeService extends IntentService  

As mentioned above, IntentService inherits Service, so this subclass must inherit service, so when was the onHandleIntent () method called? Let's look at the internal implementation of IntentService in detail:


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. 
 * 
 * @param name Used to name the worker thread, important only for debugging. 
 */ 
public IntentService(String name) { 
  super(); 
  mName = name; 
} 
 
/** 
 * Sets intent redelivery preferences. Usually called from the constructor 
 * with your preferred semantics. 
 * 
 * <p>If enabled is true, 
 * {@link #onStartCommand(Intent, int, int)} will return 
 * {@link Service#START_REDELIVER_INTENT}, so if this process dies before 
 * {@link #onHandleIntent(Intent)} returns, the process will be restarted 
 * and the intent redelivered. If multiple Intents have been sent, only 
 * the most recent one is guaranteed to be redelivered. 
 * 
 * <p>If enabled is false (the default), 
 * {@link #onStartCommand(Intent, int, int)} will return 
 * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent 
 * dies along with it. 
 */ 
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(Intent intent, int startId) { 
  Message msg = mServiceHandler.obtainMessage(); 
  msg.arg1 = startId; 
  msg.obj = intent; 
  mServiceHandler.sendMessage(msg); 
} 

Here, we can clearly see that when IntentService executes the method of onCreate, it actually opens a thread HandlerThread, obtains the looper managed by the current thread queue, and puts the message into the message queue when onStart,


@Override 
    public void handleMessage(Message msg) { 
      onHandleIntent((Intent)msg.obj); 
      stopSelf(msg.arg1); 
    } 

When the message is accepted by handler and called back, the onHandlerIntent method is executed, the implementation of which is done by the subclass.

Conclusions:

IntentService realizes a multi-threaded operation by Handler looper message, and the time-consuming operation can also be managed and executed by this thread without ANR.


Related articles: