Android应用程序启动过程源代码分析(3)
Step 16.ActivityThread.handlePauseActivity
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidhandlePauseActivity(IBindertoken,booleanfinished,
- booleanuserLeaving,intconfigChanges){
- ActivityClientRecordr=mActivities.get(token);
- if(r!=null){
- //Slog.v(TAG,"userLeaving="+userLeaving+"handlingpauseof"+r);
- if(userLeaving){
- performUserLeavingActivity(r);
- }
- r.activity.mConfigChangeFlags|=configChanges;
- Bundlestate=performPauseActivity(token,finished,true);
- //Makesureanypendingwritesarenowcommitted.
- QueuedWork.waitToFinish();
- //Telltheactivitymanagerwehavepaused.
- try{
- ActivityManagerNative.getDefault().activityPaused(token,state);
- }catch(RemoteExceptionex){
- }
- }
- }
- ......
- }
函数首先将Binder引用token转换成ActivityRecord的远程接口ActivityClientRecord,然后做了三个事情:1. 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;2. 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;3. 它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了
Step 17. ActivityManagerProxy.activityPaused
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicvoidactivityPaused(IBindertoken,Bundlestate)throwsRemoteException
- {
- Parceldata=Parcel.obtain();
- Parcelreply=Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(token);
- data.writeBundle(state);
- mRemote.transact(ACTIVITY_PAUSED_TRANSACTION,data,reply,0);
- reply.readException();
- data.recycle();
- reply.recycle();
- }
- ......
- }
这里通过Binder进程间通信机制就进入到ActivityManagerService.activityPaused函数中去了。
Step 18.ActivityManagerService.activityPaused
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicfinalvoidactivityPaused(IBindertoken,Bundleicicle){
- ......
- finallongorigId=Binder.clearCallingIdentity();
- mMainStack.activityPaused(token,icicle,false);
- ......
- }
- ......
- }
这里,又再次进入到ActivityStack类中,执行activityPaused函数。 Step 19.ActivityStack.activityPaused
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- publicclassActivityStack{
- ......
- finalvoidactivityPaused(IBindertoken,Bundleicicle,booleantimeout){
- ......
- ActivityRecordr=null;
- synchronized(mService){
- intindex=indexOfTokenLocked(token);
- if(index>=0){
- r=(ActivityRecord)mHistory.get(index);
- if(!timeout){
- r.icicle=icicle;
- r.haveState=true;
- }
- mHandler.removeMessages(PAUSE_TIMEOUT_MSG,r);
- if(mPausingActivity==r){
- r.state=ActivityState.PAUSED;
- completePauseLocked();
- }else{
- ......
- }
- }
- }
- }
- ......
- }
这里通过参数token在mHistory列表中得到ActivityRecord,从上面我们知道,这个ActivityRecord代表的是Launcher这个Activity,而我们在Step 11中,把Launcher这个Activity的信息保存在mPausingActivity中,因此,这里mPausingActivity等于r,于是,执行completePauseLocked操作。
Step 20.ActivityStack.completePauseLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- publicclassActivityStack{
- ......
- privatefinalvoidcompletePauseLocked(){
- ActivityRecordprev=mPausingActivity;
- ......
- if(prev!=null){
- ......
- mPausingActivity=null;
- }
- if(!mService.mSleeping&&!mService.mShuttingDown){
- resumeTopActivityLocked(prev);
- }else{
- ......
- }
- ......
- }
- ......
- }
函数首先把mPausingActivity变量清空,因为现在不需要它了,然后调用resumeTopActivityLokced进一步操作,它传入的参数即为代表Launcher这个Activity的ActivityRecord。
Step 21.ActivityStack.resumeTopActivityLokced
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- publicclassActivityStack{
- ......
- finalbooleanresumeTopActivityLocked(ActivityRecordprev){
- ......
- //Findthefirstactivitythatisnotfinishing.
- ActivityRecordnext=topRunningActivityLocked(null);
- //Rememberhowwe'llprocessthispause/resumesituation,andensure
- //thatthestateisresethoweverwewindupproceeding.
- finalbooleanuserLeaving=mUserLeaving;
- mUserLeaving=false;
- ......
- next.delayedResume=false;
- //Ifthetopactivityistheresumedone,nothingtodo.
- if(mResumedActivity==next&&next.state==ActivityState.RESUMED){
- ......
- returnfalse;
- }
- //Ifwearesleeping,andthereisnoresumedactivity,andthetop
- //activityispaused,wellthatisthestatewewant.
- if((mService.mSleeping||mService.mShuttingDown)
- &&mLastPausedActivity==next&&next.state==ActivityState.PAUSED){
- ......
- returnfalse;
- }
- .......
- //Weneedtostartpausingthecurrentactivitysothetopone
- //canberesumed...
- if(mResumedActivity!=null){
- ......
- returntrue;
- }
- ......
- if(next.app!=null&&next.app.thread!=null){
- ......
- }else{
- ......
- startSpecificActivityLocked(next,true,true);
- }
- returntrue;
- }
- ......
- }
通过上面的Step 9,我们知道,当前在堆栈顶端的Activity为我们即将要启动的MainActivity,这里通过调用topRunningActivityLocked将它取回来,保存在next变量中。之前最后一个Resumed状态的Activity,即Launcher,到了这里已经处于Paused状态了,因此,mResumedActivity为null。最后一个处于Paused状态的Activity为Launcher,因此,这里的mLastPausedActivity就为Launcher。前面我们为MainActivity创建了ActivityRecord后,它的app域一直保持为null。有了这些信息后,上面这段代码就容易理解了,它最终调用startSpecificActivityLocked进行下一步操作。
Step 22. ActivityStack.startSpecificActivityLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- publicclassActivityStack{
- ......
- privatefinalvoidstartSpecificActivityLocked(ActivityRecordr,
- booleanandResume,booleancheckConfig){
- //Isthisactivity'sapplicationalreadyrunning?
- ProcessRecordapp=mService.getProcessRecordLocked(r.processName,
- r.info.applicationInfo.uid);
- ......
- if(app!=null&&app.thread!=null){
- try{
- realStartActivityLocked(r,app,andResume,checkConfig);
- return;
- }catch(RemoteExceptione){
- ......
- }
- }
- mService.startProcessLocked(r.processName,r.info.applicationInfo,true,0,
- "activity",r.intent.getComponent(),false);
- }
- ......
- }
注意,这里由于是第一次启动应用程序的Activity,所以下面语句:
- ProcessRecordapp=mService.getProcessRecordLocked(r.processName,
- r.info.applicationInfo.uid);
取回来的app为null。在Activity应用程序中的AndroidManifest.xml配置文件中,我们没有指定Application标签的process属性,系统就会默认使用package的名称,这里就是"shy.luo.activity"了。每一个应用程序都有自己的uid,因此,这里uid + process的组合就可以为每一个应用程序创建一个ProcessRecord。当然,我们可以配置两个应用程序具有相同的uid和package,或者在AndroidManifest.xml配置文件的application标签或者activity标签中显式指定相同的process属性值,这样,不同的应用程序也可以在同一个进程中启动。
函数最终执行ActivityManagerService.startProcessLocked函数进行下一步操作。
Step 23.ActivityManagerService.startProcessLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- finalProcessRecordstartProcessLocked(StringprocessName,
- ApplicationInfoinfo,booleanknownToBeDead,intintentFlags,
- StringhostingType,ComponentNamehostingName,booleanallowWhileBooting){
- ProcessRecordapp=getProcessRecordLocked(processName,info.uid);
- ......
- StringhostingNameStr=hostingName!=null
- ?hostingName.flattenToShortString():null;
- ......
- if(app==null){
- app=newProcessRecordLocked(null,info,processName);
- mProcessNames.put(processName,info.uid,app);
- }else{
- //Ifthisisanewpackageintheprocess,addthepackagetothelist
- app.addPackage(info.packageName);
- }
- ......
- startProcessLocked(app,hostingType,hostingNameStr);
- return(app.pid!=0)?app:null;
- }
- ......
- }
这里再次检查是否已经有以process + uid命名的进程存在,在我们这个情景中,返回值app为null,因此,后面会创建一个ProcessRecord,并存保存在成员变量mProcessNames中,最后,调用另一个startProcessLocked函数进一步操作:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidstartProcessLocked(ProcessRecordapp,
- StringhostingType,StringhostingNameStr){
- ......
- try{
- intuid=app.info.uid;
- int[]gids=null;
- try{
- gids=mContext.getPackageManager().getPackageGids(
- app.info.packageName);
- }catch(PackageManager.NameNotFoundExceptione){
- ......
- }
- ......
- intdebugFlags=0;
- ......
- intpid=Process.start("android.app.ActivityThread",
- mSimpleProcessManagement?app.processName:null,uid,uid,
- gids,debugFlags,null);
- ......
- }catch(RuntimeExceptione){
- ......
- }
- }
- ......
- }
这里主要是调用Process.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,这就是为什么我们前面说每一个应用程序都有一个ActivityThread实例来对应的原因。
Step 24. ActivityThread.main
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidattach(booleansystem){
- ......
- mSystemThread=system;
- if(!system){
- ......
- IActivityManagermgr=ActivityManagerNative.getDefault();
- try{
- mgr.attachApplication(mAppThread);
- }catch(RemoteExceptionex){
- }
- }else{
- ......
- }
- }
- ......
- publicstaticfinalvoidmain(String[]args){
- .......
- ActivityThreadthread=newActivityThread();
- thread.attach(false);
- ......
- Looper.loop();
- .......
- thread.detach();
- ......
- }
- }
这个函数在进程中创建一个ActivityThread实例,然后调用它的attach函数,接着就进入消息循环了,直到最后进程退出。
函数attach最终调用了ActivityManagerService的远程接口ActivityManagerProxy的attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,它的作用是用来进行进程间通信的。
Step 25.ActivityManagerProxy.attachApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicvoidattachApplication(IApplicationThreadapp)throwsRemoteException
- {
- Parceldata=Parcel.obtain();
- Parcelreply=Parcel.obtain();
- data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(app.asBinder());
- mRemote.transact(ATTACH_APPLICATION_TRANSACTION,data,reply,0);
- reply.readException();
- data.recycle();
- reply.recycle();
- }
- ......
- }
这里通过Binder驱动程序,最后进入ActivityManagerService的attachApplication函数中。
Step 26.ActivityManagerService.attachApplication
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicfinalvoidattachApplication(IApplicationThreadthread){
- synchronized(this){
- intcallingPid=Binder.getCallingPid();
- finallongorigId=Binder.clearCallingIdentity();
- attachApplicationLocked(thread,callingPid);
- Binder.restoreCallingIdentity(origId);
- }
- }
- ......
- }
这里将操作转发给attachApplicationLocked函数。
Step 27.ActivityManagerService.attachApplicationLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalbooleanattachApplicationLocked(IApplicationThreadthread,
- intpid){
- //Findtheapplicationrecordthatisbeingattached...eithervia
- //thepidifwearerunninginmultipleprocesses,orjustpullthe
- //nextapprecordifweareemulatingprocesswithanonymousthreads.
- ProcessRecordapp;
- if(pid!=MY_PID&&pid>=0){
- synchronized(mPidsSelfLocked){
- app=mPidsSelfLocked.get(pid);
- }
- }elseif(mStartingProcesses.size()>0){
- ......
- }else{
- ......
- }
- if(app==null){
- ......
- returnfalse;
- }
- ......
- StringprocessName=app.processName;
- try{
- thread.asBinder().linkToDeath(newAppDeathRecipient(
- app,pid,thread),0);
- }catch(RemoteExceptione){
- ......
- returnfalse;
- }
- ......
- app.thread=thread;
- app.curAdj=app.setAdj=-100;
- app.curSchedGroup=Process.THREAD_GROUP_DEFAULT;
- app.setSchedGroup=Process.THREAD_GROUP_BG_NONINTERACTIVE;
- app.forcingToForeground=null;
- app.foregroundServices=false;
- app.debugging=false;
- ......
- booleannormalMode=mProcessesReady||isAllowedWhileBooting(app.info);
- ......
- booleanbadApp=false;
- booleandidSomething=false;
- //Seeifthetopvisibleactivityiswaitingtoruninthisprocess...
- ActivityRecordhr=mMainStack.topRunningActivityLocked(null);
- if(hr!=null&&normalMode){
- if(hr.app==null&&app.info.uid==hr.info.applicationInfo.uid
- &&processName.equals(hr.processName)){
- try{
- if(mMainStack.realStartActivityLocked(hr,app,true,true)){
- didSomething=true;
- }
- }catch(Exceptione){
- ......
- }
- }else{
- ......
- }
- }
- ......
- returntrue;
- }
- ......
- }
在前面的Step 23中,已经创建了一个ProcessRecord,这里首先通过pid将它取回来,放在app变量中,然后对app的其它成员进行初始化,最后调用mMainStack.realStartActivityLocked执行真正的Activity启动操作。这里要启动的Activity通过调用mMainStack.topRunningActivityLocked(null)从堆栈顶端取回来,这时候在堆栈顶端的Activity就是MainActivity了。
更多相关文章
- Android应用程序启动过程源代码分析(2)
- android WebView java与js相互调用
- Momo自定义DialogFragment
- android快捷卸载第三方应用
- Android(安卓)2D绘图总结
- android 调用系统应用
- android实现调用系统音乐播放器
- Debug native code using addr2line on Android--再转一个Androi
- 自定义Android(安卓)editText