Just An Application

May 17, 2012

Adventures In Distributed Garbage Collection: Part Seven – Service Destruction

1.0 Service Component Destruction

The component which implements a Service is destroyed either

  • when the Service is explicitly stopped, either by a client or by the Service itself, and there are no current clients of the Service who specified the BIND_AUTO_CREATE flag when they bound to it, or

  • when a client which specified the BIND_AUTO_CREATE flag when it bound to the Service unbinds from it, and there are no other clients of the Service who
    specified the BIND_AUTO_CREATE flag when they bound to it

2.0 Process: System

Actor: ActivityManagerService

2.1 Stopping A Service

A Service is stopped via a remote procedure call to either the ActivityManagerService implementation of the IActivityManager method

     public int stopService(IApplicationThread caller, Intent service, String resolvedType) 
                throws 
                    RemoteException

or the ActivityManagerService implementation of the IActivityManager method

     public boolean stopServiceToken(ComponentName className, IBinder token, int startId)
                    throws
                        RemoteException

Both methods call the method bringDownServiceLocked() to stop the Service.

2.2 Unbinding From A Service

A client unbinds from a Service via a remote procedure call to the ActivityManagerService implementation of the IActivityManager method

    public boolean unbindService(IServiceConnection connection) 
                   throws 
                       RemoteException;

A call to this method can result in a call to the method bringDownServiceLocked() to stop the Service.

2.3 Methods

2.3.1 bringDownServiceLocked(…)

Definition: ActivityManagerService.java [9016-9142]

    private final void bringDownServiceLocked(ServiceRecord r, boolean force) 

Argument: ServiceRecord r

  • The ServiceRecord which represents the Service that should be stopped.

Argument: boolean force

  • true if the Service should be forced to stop.

Method

Checking Whether To Stop The Service

If force is false and the Service was started explicitly then the method returns immediately.

If there are connections associated with the Service and force is false then the method iterates over all the ConnectionRecords in the connections map of the ServiceRecord.

If the BIND_AUTO_CREATE flag is set in the flags instance variable of a ConnectionRecord the method returns immediately.

Preparing To Stop The Service

If there are connections associated with the Service then for each ConnectionRecord in the connections map of the ServiceRecord the method calls connected() on the IServiceConnection object held by the ConnectionRecord (conn) passing null as the second argument to indicate that the connection is being disconnected.

Each call results in an asynchronous remote procedure call to the object implementing the IServiceConnection in the process which created the connection.

If the Service is running, then, for each IntentBindRecord in the bindings map of the ServiceRecord the method calls bumpServiceExecutingLocked(), sets the hasBound instance variable of the IntentBindRecord to false, and then calls scheduleUnbindService() on the ApplicationThreadProxy held by the ProcessRecord which is held by the ServiceRecord.

Stopping The Service

The ServiceRecord is removed from the mServices and mServicesByIntent maps.

If the ServiceRecord has an associated ProcessRecord then

The ServiceRecord is removed from the services set of the ProcessRecord.

If the ProcessRecord has a proxy for the ApplicationThread in the process running the Service then

The method bumpServiceExecutingLocked() is called.

The ServiceRecord is added to the mStoppingServices list.

The method scheduleStopService() is called on the ApplicationThreadProxy.

This results in an asynchronous remote procedure to the ApplicationThread implementation of the scheduleStopService() method in the process running the Service.

3.0 Process: Service

Entry Point: remote procedure call to the ApplicationThread implementation of the IApplicationThread method scheduleStopService().

3.1 scheduleStopService(…)

Caller: The ActivityManagerService via remote procedure call.

Actor: ApplicationThread

Definition: ActivityThread.java [531-533]

    public final void scheduleStopService(IBinder token)

Argument: IBinder token

  • The proxy for the ServiceRecord which represents the Service to be stopped.

Method

The method forwards the token argument to the ActivityThread in a message.

This message is handled by the ActivityThread method handleStopService().

3.2 handleStopService(…)

Actor: ActivityThread

Definition: ActivityThread.java [2060-2089]

    private final void handleStopService(IBinder token)

Argument: IBinder token

  • The proxy for the ServiceRecord which represents the Service to be stopped.

Method

The method begins by retrieving the Service Component object to stop by removing it from the mServices map using the token argument as the key.

If the corresponding Service Component object is not found then the method does nothing more.

Otherwise it calls onDestroy() on the Service Component object.

It then cleans up the Service’s context before calling serviceDoneExecuting() on the ActivityManagerProxy instance returned by a call to the static method ActivityManagerNative.getDefault().

This results in an asynchronous remote procedure call to the ActivityManagerService implementation of the serviceDoneExecuting() method.


Copyright (c) 2012 By Simon Lewis. All Rights Reserved.

Advertisements

2 Comments »

  1. […] flag was set when the connection represented by the ConnectionRecord was created the method calls bringDownServiceLocked() passing it the ServiceRecord and with the force argument set to […]

    Pingback by Adventures In Distributed Garbage Collection: Part Twelve – Unbinding From A Service « Just An Application — May 23, 2012 @ 6:01 am

  2. […] the HashMap referenced by the bindings instance variable of the ServiceRecord. This is done in the bringDownServiceLocked() method of the ActivityManagerService. Doing this breaks the reference between the ServiceRecord and […]

    Pingback by Adventures In Distributed Garbage Collection: Part Eighteen – The Great Service Record Mystery Revisited « Just An Application — June 6, 2012 @ 9:32 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: