Android startservice process sorting notes

Source: Internet
Author: User
Tags switch case

1. contextwrapper. startservice

Startservice is the context method. Both activity and service inherit from contextwrapper, while contextwrapper inherits from context. The onreceive method of broadcastreceiver has a parameter of the context type, therefore, the startservice method can be called in activity, service, and broadcastreceiver. When startservice is called in activity, the startservice method of contextwrapper is called first:

 
Public componentname startservice (intent Service) {return mbase. startservice (service );}

2. contextimpl. startservice

Mbase is an instance of contextimpl. You can see from the name that contextimpl is also a subclass of context. From the name of contextwrapper, you can also see that it is only a packaging class of context, the internal implementation of the function is to call the internal contextimpl class instance mbase to complete the actual request, which is called the decorator mode.

Startservice of contextimpl calls startserviceasuser directly and activitymanagernative. getdefault (). startservice, activitymanagernative. getdefault () in startserviceasuser to return an iactivitymanager object, which is a typical binder communication. Therefore, the startservice of activitymanagerproxy is called to the startservice method of activitymanagerservice (inherited from activitymanagernative) through the binder.

 
Public componentname startserviceasuser (intent service, userhandle user) {try {service. setallowfds (false); componentname Cn = activitymanagernative. getdefault (). startservice (mmainthread. getapplicationthread (), service, service. resolvetypeifneeded (getcontentresolver (), user. getidentifier ());... return CN;} catch (RemoteException e) {return NULL ;}}

3. activitymanagerservice. startservice and activeservices

In startservice of activitymanagerservice, first check the legitimacy of caller (PID, UID), then call the startservicelocked method of activeservices (in earlier versions, this method is in activitymanagerservice), in startservicelocked, first, use retrieveservicelocked to retrieve the intent information we passed in when calling startservice, and store the result to servicelookupresult. in the record (servicerecord), and then call the bringupservicelocked method of activeservices.

Call startprocesslocked of activitymanagerservice in bringupservicelocked to obtain a processrecord object and add it to the mpendingservices queue. Startservicelocked and bringupservicelocked are all called from activitymanagerservice. Therefore, they are always running in the activityamanagerservice process. The method to call activitymanagerservice is called directly instead of using IPC.

activitymanagerservice has two reloads of startprocesslocked. First, enter the one with multiple parameters, obtain a processrecord object through newprocessrecordlocked, and call startprocesslocked in another form as a parameter. In this startprocesslocked, process is called. start creates a new process and returns the process. the processstartresult object, the PID of the new process, and the obtained processrecord object are placed in the mpidselflocked list.

Final processrecord startprocesslocked (string processname, applicationinfo info, Boolean knowntobedead, int intentflags, string hostingtype, componentname hostingname, Boolean allowwhilebooting, Boolean isolated ){... APP = newprocessrecordlocked (null, info, processname, isolated );... startprocesslocked (app, hostingtype, hostingnamestr); Return (App. PID! = 0 )? APP: NULL;} private final void startprocesslocked (processrecord app, string hostingtype, string hostingnamestr ){... process. processstartresult startresult = process. start ("android. app. activitythread ", app. processname, uid, uid, gids, debugflags, mountexternal, app.info.tar getsdkversion, null, null );... synchronized (mpidsselflocked) {This. mpidsselflocked. put (startresult. PID, APP );...}...}

4. activitythread. Main

Create a process in process. Start and call the main function of activitythread.

 
Public static void main (string [] ARGs ){... logoff. preparemainlooper (); activitythread thread = new activitythread (); thread. attach (false); If (smainthreadhandler = NULL) {smainthreadhandler = thread. gethandler ();}... logoff. loop ();...}

5. activitymanagerservice. attachapplication

Create an activitythread object in main and call its attach method. The parameter indicates whether it is a system process. This is already in the new process. In attach, activitymanagernative. getdefault (). attachapplication (mappthread) is called ). Similarly, through the binder from activitymanagerproxy to the activitymanagerservice attachapplication method, directly call attachapplicationlocked in the attachapplication.

In attachapplicationlocked, use the PID of the new process to obtain the processrecord object in the mpidselflocked list in step 1, and then call the attachapplicationlocked method of activeyservices, in this method, find the servicerecord object in mpendingservices in step 1 through the process PID and process name, and call realstartservicelocked using the servicerecord object and the passed processrecord object as the parameter, this function is also in activeservices.

Private Final Boolean attachapplicationlocked (iapplicationthread thread, nt pid) {processrecord app; If (PID! = My_pid & pid> = 0) {synchronized (mpidsselflocked) {APP = mpidsselflocked. get (PID) ;}} else {APP = NULL ;}... mservices. attachapplicationlocked (app, processname );...} boolean attachapplicationlocked (processrecord proc, string processname) throws exception {Boolean didsomething = false; // collect any services that are waiting for this process to come up. if (mpendingservices. size ()> 0 ){ Servicerecord sr = NULL; try {for (INT I = 0; I <mpendingservices. Size (); I ++) {sr = mpendingservices. Get (I); If (Proc! = Sr. isolatedproc & (Proc. uid! = Sr. appinfo. uid |! Processname. equals (Sr. processname) {continue;} mpendingservices. remove (I); I --; realstartservicelocked (Sr, Proc); didsomething = true ;}} catch (exception e) {slog. W (TAG, "exception in new application when starting service" + sr. shortname, e); throw e ;}}...}

6, Activeservices. realstartservicelocked

In realstartservicelocked, obtain the iapplicationthread member variable of the passed processrecord object and call its schedulecreateservice method. Like activitymanagerproxy, schedulecreateservice of applicationthreadproxy is called, then, schedulecreateservice from binder to applicationthread (applicationthread is the private internal class of activitythread ).

7. applicationthread. schedulecreateservice and activitythread. handlecreateservice

In schedulecreateservice of applicationthread, The queueorsendmessage method of the external activitythread is called, and the sendmessage (H inherited from handler) is sent to H. Next, the handlemessage of H is affirmed, in handlemessage, use the create_service switch case to call the handlecreateservice method of the external activitythread class.

load the class of the service to be started on handlecreateservice through the Java classloader load, and create a service instance through newinstance, new contextimpl, makeapplication and attach the new service instance, and then call the oncreate method of the familiar service. At this point, the service is started successfully.

Private void handlecreateservice (createservicedata data) {// if we are getting ready to GC after going to the background, well // We are back active so skip it. unschedulegcidler (); loadedapk packageinfo = getpackageinfonocheck (data.info. applicationinfo, Data. compatinfo); service = NULL; try {Java. lang. classloader Cl = packageinfo. getclassloader (); service = (service) Cl. loadclass (data.info. name ). newinstance ();} catch (exception e ){...} try {If (locallogv) slog. V (TAG, "creating service" + data.info. name); contextimpl context = new contextimpl (); context. init (packageinfo, null, this); Application APP = packageinfo. makeapplication (false, minstrumentation); context. setoutercontext (service); service. attach (context, this, data.info. name, Data. token, app, activitymanagernative. getdefault (); // call the oncreate service of the service, that is, the oncreate service of the service to be started. oncreate (); mservices. put (data. token, service); try {activitymanagernative. getdefault (). servicedoneexecuting (data. token, 0, 0, 0);} catch (RemoteException e) {// nothing to do .}} catch (exception e ){...}}

 

Summary:

1. Call the startservice of contextimpl and run the startservice method of activitymanagerservice by entering the activitymanagerservice process through the binder.

2. Create a new process in the startservice process, create logoff in the new process, call the attach method of activitythread, and then enter the activitymanagerservice process.

3. Get the information about the service to be started in the new process. In activitymanagerservice, use applicationthreadproxy to enter the service process again. The service process starts and calls the oncreate method of the service we are familiar.

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.