Five core modules of Android applications-Service background services
Concept:
Service: A Background Service that puts some common computing or system functions in an independent process for processing. In this way, the main process can fully and quickly process interface responses to improve user experience.
The following uses packages \ apps \ Phone as an example:
Android manifest. xml
<! -- CDMA Emergency Callback Mode -->
<Service android: name = "EmergencyCallbackModeService">
</Service>
The definition in EmergencyCallbackModeService. java is as follows:
Public class EmergencyCallbackModeService extends Service
It inherits from the android. app. Service class and reloads its parent class function. The Service Startup point is:
PhoneAppBroadcastReceiver @ PhoneApp. java
// Start Emergency Callback Mode service
If (intent. getBooleanExtra ("phoneinECMState", false )){
Context. startService (new Intent (context,
EmergencyCallbackModeService. class ));
}
OK. The Servie service starts with the Intent class by using the startService function in the table.
The relationships between several classes are as follows:
Public abstract class Context
Public class ContextImpl extends Context
Public class ContextWrapper extends Context
Public class ContextThemeWrapper extends ContextWrapper
Public class Activity extends ContextThemeWrapper
That is, Activity inherits the ContextWrapper class, while in the ContextWrapper class, startService function is implemented. In the ContextWrapper class, there is a member variable mBase, which is a ContextImpl instance, while the ContextImpl class inherits from the Context class like the ContextWrapper class, the startService function of the ContextWrapper class is implemented by calling the startService function of the ContextImpl class.
Now that you have understood these relationships, follow the code below to go through the complete process:
===================================== The main process calls the ActivityManagerService process, create a new process ==============
StartService @ ContextImpl. java
Public ComponentName startService (Intent service ){
ComponentName cn = ActivityManagerNative. getDefault (). startService (
MMainThread. getApplicationThread (), service,
Service. resolveTypeIfNeeded (getContentResolver ()));
}
Binder is used for communication:
StartService @ ActivityManagerNative. java
MRemote. transact (START_SERVICE_TRANSACTION, data, reply, 0 );
The Binder driver is used to send a request to the reporting client, that is, the mRemote (Binder object) is the ActivityManagerService.
ActivityManagerService is waiting for Client requests:
StartService @ ActivityManagerService. java
Public ComponentName startService (IApplicationThread caller, Intent service,
String resolvedType ){
// Obtain parameters such as pid and uid using the Binder object
Final int callingPid = Binder. getCallingPid ();
Final int callingUid = Binder. getCallingUid ();
Final long origId = Binder. clearCallingIdentity ();
ComponentName res = startServiceLocked (caller, service,
ResolvedType, callingPid, callingUid );
}
Caller, service, and resolvedType correspond to the three parameters passed in by ActivityManagerProxy. startService.
-->
Here is a brief look at the call logic:
StartServiceLocked () --> bringUpServiceLocked () --> startProcessLocked:
Private final void startProcessLocked (ProcessRecord app,
String hostingType, String hostingNameStr ){
....
Int pid = Process. start ("android. app. ActivityThread ",
MSimpleProcessManagement? App. processName: null, uid, uid,
Gids, debugFlags, null );
...
}
Start @ Process. java
Public static final int start (final String processClass,
Final String niceName,
Int uid, int gid, int [] gids,
Int debugFlags,
String [] zygoteArgs)
{
If (supportsProcesses ()){
Return startViaZygote (processClass, niceName, uid, gid, gids,
DebugFlags, zygoteArgs );
} Else {
// Running in single-process mode
Process. invokeStaticMain (processClass );
}
}
The function openZygoteSocketIfNeeded and Zygote Socket are used for communication.
Process, and then import the android. app. ActivityThread thread to execute its main function.
========= The new process calls the ActivityManagerService process to obtain information about the service to be started in the new process ======
Main @ ActivityThread. java
Public static final void main (String [] args ){
// Set the active Logoff of the Activity.
Lorule. preparemainlorule ();
// Create an ActivityThread thread instance www.2cto.com
ActivityThread thread = new ActivityThread ();
Thread. attach (false );
Logoff. loop ();
}
It runs in a new process and starts the service. In Android applications, each process corresponds to an ActivityThread instance. Therefore, this function creates a thread instance and calls the ActivityThread. attach function for further processing.
Attach @ ActivityThread. java
Private final void attach (boolean system ){
...
IActivityManager mgr = ActivityManagerNative. getDefault ();
Try {
Mgr. attachApplication (mAppThread );
} Catch (RemoteException ex ){
}
}
Yo, we have to call ActivityManagerNative again here. Well, according to the previous analysis, you should know it :)
AttachApplication @ ActivityManagerNative. java
MRemote. transact (ATTACH_APPLICATION_TRANSACTION, data, reply, 0 );
Call to the server using the Binder object:
AttachApplication @ ActivityManagerService. java
AttachApplicationLocked
Private final boolean attachApplicationLocked (IApplicationThread thread,
Int pid ){
// Find any services that shocould be running in this process...
If (! BadApp & mPendingServices. size ()> 0 ){
RealStartServiceLocked (sr, app );
}
}
-->
At the beginning, we used the mPidsSelfLocked variable to save some information about the process to the ServiceRecord class.
App. thread. scheduleCreateService (r, r. serviceInfo );
ScheduleCreateService @ ApplicationThreadNative. java
Public final void scheduleCreateService (IBinder token, ServiceInfo info ){
MRemote. transact (SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
IBinder. FLAG_ONEWAY );
}
Return to the ApplicationThread object of the new process using the Binder driver to execute the scheduleCreateService function.
============== Return from the ActivityManagerService process to the new process, and finally start the service ==============
ScheduleCreateService @ ActivityThread. java
Public final void scheduleCreateService (IBinder token,
ServiceInfo info ){
CreateServiceData s = new CreateServiceData ();
S. token = token;
S.info = info;
QueueOrSendMessage (H. CREATE_SERVICE, s );
}
Send messages through Handler and call lorule. preparemainlogoff () in the main function of this file. This indicates that this is an Activity main thread, which uses the main lorule to process cyclic messages by the loop in lorule. java.
Message Processing functions:
HandleMessage @ ActivityThread. java
Public void handleMessage (Message msg ){
Case CREATE_SERVICE:
HandleCreateService (CreateServiceData) msg. obj );
Break;
...
}
-->
Private final void handleCreateService (CreateServiceData data ){
Service service = null;
// Obtain a Service class instance through forced type conversion
Java. lang. ClassLoader cl = packageInfo. getClassLoader ();
Service = (Service) cl. loadClass (data.info. name). newInstance ();
...
Service. onCreate ();
}
As mentioned above, your Service class must inherit from the Service class, so the onCreate () function of your Service will be run.
Public class EmergencyCallbackModeService extends Service {
@ Override
Public void onCreate (){
// Check if it is CDMA phone
...
}
Summary:
In this way, the process of starting services in the new process of the Android system is analyzed. The main process is as follows:
1. The main process is called to the ActivityManagerService process to create a new process.
2. The new process calls the ActivityManagerService process to obtain information about the service to be started in the new process.
3. Return from the ActivityManagerService process to the new process and start the service.
The above three Binder processes communicate with each other to complete the startup process.
The following is a brief illustration:
From andyhuabing's column