首页 文章 精选 留言 我的

精选列表

搜索[源代码漏洞],共10002篇文章
优秀的个人博客,低调大师

Android应用程序启动过程源代码分析(5)

Step 35. MainActivity.onCreate 这个函数定义在packages/experimental/Activity/src/shy/luo/activity/MainActivity.java文件中,这是我们自定义的app工程文件: publicclassMainActivityextendsActivityimplementsOnClickListener{ ...... @Override publicvoidonCreate(BundlesavedInstanceState){ ...... Log.i(LOG_TAG,"MainActivityCreated."); } ...... } 这样,MainActivity就启动起来了,整个应用程序也启动起来了。 整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段: 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity; 二. Step 12 - Step 16:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态; 三. Step 17 - Step 24:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行; 四. Step 25 - Step 27:ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信; 五. Step 28 - Step 35:ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。 这里不少地方涉及到了Binder进程间通信机制,相关资料请参考Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。 这样,应用程序的启动过程就介绍完了,它实质上是启动应用程序的默认Activity,在下一篇文章中,我们将介绍在应用程序内部启动另一个Activity的过程,即新的Activity与启动它的Activity将会在同一个进程(Process)和任务(Task)运行,敬请关注。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/965993,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序启动过程源代码分析(2)

Step 8. ActivityStack.startActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中: public classActivityStack{ ...... final intstartActivityLocked(IApplicationThreadcaller, Intentintent,StringresolvedType, Uri[]grantedUriPermissions, intgrantedMode,ActivityInfoaInfo,IBinderresultTo, StringresultWho, intrequestCode, intcallingPid, intcallingUid, booleanonlyIfNeeded, booleancomponentSpecified){ interr=START_SUCCESS; ProcessRecordcallerApp= null; if(caller!= null){ callerApp=mService.getRecordForAppLocked(caller); if(callerApp!= null){ callingPid=callerApp.pid; callingUid=callerApp.info.uid; } else{ ...... } } ...... ActivityRecordsourceRecord= null; ActivityRecordresultRecord= null; if(resultTo!= null){ intindex=indexOfTokenLocked(resultTo); ...... if(index>= 0){ sourceRecord=(ActivityRecord)mHistory.get(index); if(requestCode>= 0&&!sourceRecord.finishing){ ...... } } } intlaunchFlags=intent.getFlags(); if((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT)!= 0 &&sourceRecord!= null){ ...... } if(err==START_SUCCESS&&intent.getComponent()== null){ ...... } if(err==START_SUCCESS&&aInfo== null){ ...... } if(err!=START_SUCCESS){ ...... } ...... ActivityRecordr= newActivityRecord(mService, this,callerApp,callingUid, intent,resolvedType,aInfo,mService.mConfiguration, resultRecord,resultWho,requestCode,componentSpecified); ...... returnstartActivityUncheckedLocked(r,sourceRecord, grantedUriPermissions,grantedMode,onlyIfNeeded, true); } ...... } 从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了。 前面说过,参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。 再接下来,创建即将要启动的Activity的相关信息,并保存在r变量中: ActivityRecordr= newActivityRecord(mService, this,callerApp,callingUid, intent,resolvedType,aInfo,mService.mConfiguration, resultRecord,resultWho,requestCode,componentSpecified); 接着调用startActivityUncheckedLocked函数进行下一步操作。 Step 9. ActivityStack.startActivityUncheckedLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中: public classActivityStack{ ...... final intstartActivityUncheckedLocked(ActivityRecordr, ActivityRecordsourceRecord,Uri[]grantedUriPermissions, intgrantedMode, booleanonlyIfNeeded, booleandoResume){ finalIntentintent=r.intent; final intcallingUid=r.launchedFromUid; intlaunchFlags=intent.getFlags(); //We'llinvokeonUserLeavingbeforeonPauseonlyifthelaunching //activitydidnotexplicitlystatethatthisisanautomatedlaunch. mUserLeaving=(launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION)== 0; ...... ActivityRecordnotTop=(launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0?r: null; //IftheonlyIfNeededflagisset,thenwecandothisiftheactivity //beinglaunchedisthesameastheonemakingthecall...or,as //aspecialcase,ifwedonotknowthecallerthenwecountthe //currenttopactivityasthecaller. if(onlyIfNeeded){ ...... } if(sourceRecord== null){ ...... } else if(sourceRecord.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE){ ...... } else if(r.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_TASK){ ...... } if(r.resultTo!= null&&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0){ ...... } booleanaddingToTask= false; if(((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0&& (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK)== 0) ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_TASK ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE){ //Ifbringtofrontisrequested,andnoresultisrequested,and //wecanfindataskthatwasstartedwiththissame //component,theninsteadoflaunchingbringthatonetothefront. if(r.resultTo== null){ //Seeifthereisatasktobringtothefront.Ifthisis //aSINGLE_INSTANCEactivity,therecanbeoneandonlyone //instanceofitinthehistory,anditisalwaysinitsown //uniquetask,sowedoaspecialsearch. ActivityRecordtaskTop=r.launchMode!=ActivityInfo.LAUNCH_SINGLE_INSTANCE ?findTaskLocked(intent,r.info) :findActivityLocked(intent,r.info); if(taskTop!= null){ ...... } } } ...... if(r.packageName!= null){ //Iftheactivitybeinglaunchedisthesameastheonecurrently //atthetop,thenweneedtocheckifitshouldonlybelaunched //once. ActivityRecordtop=topRunningNonDelayedActivityLocked(notTop); if(top!= null&&r.resultTo== null){ if(top.realActivity.equals(r.realActivity)){ ...... } } } else{ ...... } booleannewTask= false; //Shouldthisbeconsideredanewtask? if(r.resultTo== null&&!addingToTask &&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0){ //todo:shoulddobettermanagementofintegers. mService.mCurTask++; if(mService.mCurTask<= 0){ mService.mCurTask= 1; } r.task= newTaskRecord(mService.mCurTask,r.info,intent, (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH)!= 0); ...... newTask= true; if(mMainStack){ mService.addRecentTaskLocked(r.task); } } else if(sourceRecord!= null){ ...... } else{ ...... } ...... startActivityLocked(r,newTask,doResume); returnSTART_SUCCESS; } ...... } 函数首先获得intent的标志值,保存在launchFlags变量中。 这个intent的标志值的位Intent.FLAG_ACTIVITY_NO_USER_ACTION没有置位,因此 ,成员变量mUserLeaving的值为true。 这个intent的标志值的位Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP也没有置位,因此,变量notTop的值为null。 由于在这个例子的AndroidManifest.xml文件中,MainActivity没有配置launchMode属值,因此,这里的r.launchMode为默认值0,表示以标准(Standard,或者称为ActivityInfo.LAUNCH_MULTIPLE)的方式来启动这个Activity。Activity的启动方式有四种,其余三种分别是ActivityInfo.LAUNCH_SINGLE_INSTANCE、ActivityInfo.LAUNCH_SINGLE_TASK和ActivityInfo.LAUNCH_SINGLE_TOP,具体可以参考官方网站 http://developer.android.com/reference/android/content/pm/ActivityInfo.html。 传进来的参数r.resultTo为null,表示Launcher不需要等这个即将要启动的MainActivity的执行结果。 由于这个intent的标志值的位Intent.FLAG_ACTIVITY_NEW_TASK被置位,而且Intent.FLAG_ACTIVITY_MULTIPLE_TASK没有置位,因此,下面的if语句会被执行: if(((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0&& (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK)== 0) ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_TASK ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE){ //Ifbringtofrontisrequested,andnoresultisrequested,and //wecanfindataskthatwasstartedwiththissame //component,theninsteadoflaunchingbringthatonetothefront. if(r.resultTo== null){ //Seeifthereisatasktobringtothefront.Ifthisis //aSINGLE_INSTANCEactivity,therecanbeoneandonlyone //instanceofitinthehistory,anditisalwaysinitsown //uniquetask,sowedoaspecialsearch. ActivityRecordtaskTop=r.launchMode!=ActivityInfo.LAUNCH_SINGLE_INSTANCE ?findTaskLocked(intent,r.info) :findActivityLocked(intent,r.info); if(taskTop!= null){ ...... } } } 这段代码的逻辑是查看一下,当前有没有Task可以用来执行这个Activity。由于r.launchMode的值不为ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过findTaskLocked函数来查找存不存这样的Task,这里返回的结果是null,即taskTop为null,因此,需要创建一个新的Task来启动这个Activity。 接着往下看: if(r.packageName!= null){ //Iftheactivitybeinglaunchedisthesameastheonecurrently //atthetop,thenweneedtocheckifitshouldonlybelaunched //once. ActivityRecordtop=topRunningNonDelayedActivityLocked(notTop); if(top!= null&&r.resultTo== null){ if(top.realActivity.equals(r.realActivity)){ ...... } } } 这段代码的逻辑是看一下,当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了,具体可以参考官方网站 http://developer.android.com/reference/android/content/pm/ActivityInfo.html 。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,因此,这里不用进一步处理上述介绍的情况。 执行到这里,我们知道,要在一个新的Task里面来启动这个Activity了,于是新创建一个Task: if(r.resultTo== null&&!addingToTask &&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0){ //todo:shoulddobettermanagementofintegers. mService.mCurTask++; if(mService.mCurTask<= 0){ mService.mCurTask= 1; } r.task= newTaskRecord(mService.mCurTask,r.info,intent, (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH)!= 0); ...... newTask= true; if(mMainStack){ mService.addRecentTaskLocked(r.task); } } 新建的Task保存在r.task域中,同时,添加到mService中去,这里的mService就是ActivityManagerService了。 最后就进入startActivityLocked(r, newTask, doResume)进一步处理了。这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中: public classActivityStack{ ...... private final voidstartActivityLocked(ActivityRecordr, booleannewTask, booleandoResume){ final intNH=mHistory.size(); intaddPos=- 1; if(!newTask){ ...... } //Placeanewactivityattopofstack,soitisnexttointeract //withtheuser. if(addPos< 0){ addPos=NH; } //Ifwearenotplacingthenewactivityfrontmost,wedonotwant //todelivertheonUserLeavingcallbacktotheactualfrontmost //activity if(addPos<NH){ ...... } //Slottheactivityintothehistorystackandproceed mHistory.add(addPos,r); r.inHistory= true; r.frontOfTask=newTask; r.task.numActivities++; if(NH> 0){ //Wewanttoshowthestartingpreviewwindowifweare //switchingtoanewtask,orthenextactivity'sprocessis //notcurrentlyrunning. ...... } else{ //Ifthisisthefirstactivity,don'tdoanyfancyanimations, //becausethereisnothingforittoanimateontopof. ...... } ...... if(doResume){ resumeTopActivityLocked( null); } } ...... } 这里的NH表示当前系统中历史任务的个数,这里肯定是大于0,因为Launcher已经跑起来了。当NH>0时,并且现在要切换新任务时,要做一些任务切的界面操作,这段代码我们就不看了,这里不会影响到下面启Activity的过程,有兴趣的读取可以自己研究一下。 这里传进来的参数doResume为true,于是调用resumeTopActivityLocked进一步操作。 Step 10. Activity.resumeTopActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中: public classActivityStack{ ...... /** *Ensurethatthetopactivityinthestackisresumed. * *@paramprevThepreviouslyresumedactivity,forwhenintheprocess *ofpausing;canbenulltocallfromelsewhere. * *@returnReturnstrueifsomethingisbeingresumed,orfalseif *nothinghappened. */ final booleanresumeTopActivityLocked(ActivityRecordprev){ //Findthefirstactivitythatisnotfinishing. ActivityRecordnext=topRunningActivityLocked( null); //Rememberhowwe'llprocessthispause/resumesituation,andensure //thatthestateisresethoweverwewindupproceeding. final booleanuserLeaving=mUserLeaving; mUserLeaving= false; if(next== null){ ...... } next.delayedResume= false; //Ifthetopactivityistheresumedone,nothingtodo. if(mResumedActivity==next&&next.state==ActivityState.RESUMED){ ...... } //Ifwearesleeping,andthereisnoresumedactivity,andthetop //activityispaused,wellthatisthestatewewant. if((mService.mSleeping||mService.mShuttingDown) &&mLastPausedActivity==next&&next.state==ActivityState.PAUSED){ ...... } ...... //Ifwearecurrentlypausinganactivity,thendon'tdoanything //untilthatisdone. if(mPausingActivity!= null){ ...... } ...... //Weneedtostartpausingthecurrentactivitysothetopone //canberesumed... if(mResumedActivity!= null){ ...... startPausingLocked(userLeaving, false); return true; } ...... } ...... } 函数先通过调用topRunningActivityLocked函数获得堆栈顶端的Activity,这里就是MainActivity了,这是在上面的Step 9设置好的,保存在next变量中。 接下来把mUserLeaving的保存在本地变量userLeaving中,然后重新设置为false,在上面的Step 9中,mUserLeaving的值为true,因此,这里的userLeaving为true。 这里的mResumedActivity为Launcher,因为Launcher是当前正被执行的Activity。 当我们处理休眠状态时,mLastPausedActivity保存堆栈顶端的Activity,因为当前不是休眠状态,所以mLastPausedActivity为null。 有了这些信息之后,下面的语句就容易理解了: //Ifthetopactivityistheresumedone,nothingtodo. if(mResumedActivity==next&&next.state==ActivityState.RESUMED){ ...... } //Ifwearesleeping,andthereisnoresumedactivity,andthetop //activityispaused,wellthatisthestatewewant. if((mService.mSleeping||mService.mShuttingDown) &&mLastPausedActivity==next&&next.state==ActivityState.PAUSED){ ...... } 它首先看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一下系统当前是否休眠状态,如果是的话,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做。 上面两个条件都不满足,因此,在继续往下执行之前,首先要把当处于Resumed状态的Activity推入Paused状态,然后才可以启动新的Activity。但是在将当前这个Resumed状态的Activity推入Paused状态之前,首先要看一下当前是否有Activity正在进入Pausing状态,如果有的话,当前这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样就保证了所有需要进入Paused状态的Activity串行处理。 这里没有处于Pausing状态的Activity,即mPausingActivity为null,而且mResumedActivity也不为null,于是就调用startPausingLocked函数把Launcher推入Paused状态去了。 Step 11. ActivityStack.startPausingLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中: public classActivityStack{ ...... private final voidstartPausingLocked( booleanuserLeaving, booleanuiSleeping){ if(mPausingActivity!= null){ ...... } ActivityRecordprev=mResumedActivity; if(prev== null){ ...... } ...... mResumedActivity= null; mPausingActivity=prev; mLastPausedActivity=prev; prev.state=ActivityState.PAUSING; ...... if(prev.app!= null&&prev.app.thread!= null){ ...... try{ ...... prev.app.thread.schedulePauseActivity(prev,prev.finishing,userLeaving, prev.configChangeFlags); ...... } catch(Exceptione){ ...... } } else{ ...... } ...... } ...... } 函数首先把mResumedActivity保存在本地变量prev中。在上一步Step 10中,说到mResumedActivity就是Launcher,因此,这里把Launcher进程中的ApplicationThread对象取出来,通过它来通知Launcher这个Activity它要进入Paused状态了。当然,这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。 参数prev.finishing表示prev所代表的Activity是否正在等待结束的Activity列表中,由于Laucher这个Activity还没结束,所以这里为false;参数prev.configChangeFlags表示哪些config发生了变化,这里我们不关心它的值。 Step 12.ApplicationThreadProxy.schedulePauseActivity 这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中: classApplicationThreadProxy implementsIApplicationThread{ ...... public final voidschedulePauseActivity(IBindertoken, booleanfinished, booleanuserLeaving, intconfigChanges) throwsRemoteException{ Parceldata=Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); data.writeInt(finished? 1: 0); data.writeInt(userLeaving? 1: 0); data.writeInt(configChanges); mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,data, null, IBinder.FLAG_ONEWAY); data.recycle(); } ...... } 这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中。 Step 13. ApplicationThread.schedulePauseActivity 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中,它是ActivityThread的内部类: public final classActivityThread{ ...... private final classApplicationThread extendsApplicationThreadNative{ ...... public final voidschedulePauseActivity(IBindertoken, booleanfinished, booleanuserLeaving, intconfigChanges){ queueOrSendMessage( finished?H.PAUSE_ACTIVITY_FINISHING:H.PAUSE_ACTIVITY, token, (userLeaving? 1: 0), configChanges); } ...... } ...... } 这里调用的函数queueOrSendMessage是ActivityThread类的成员函数。 上面说到,这里的finished值为false,因此,queueOrSendMessage的第一个参数值为H.PAUSE_ACTIVITY,表示要暂停token所代表的Activity,即Launcher。 Step 14. ActivityThread.queueOrSendMessage 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中: public final classActivityThread{ ...... private final voidqueueOrSendMessage( intwhat,Objectobj, intarg1){ queueOrSendMessage(what,obj,arg1, 0); } private final voidqueueOrSendMessage( intwhat,Objectobj, intarg1, intarg2){ synchronized( this){ ...... Messagemsg=Message.obtain(); msg.what=what; msg.obj=obj; msg.arg1=arg1; msg.arg2=arg2; mH.sendMessage(msg); } } ...... } 这里首先将相关信息组装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage来处理。 Step 15. H.handleMessage 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中: public final classActivityThread{ ...... private final classH extendsHandler{ ...... public voidhandleMessage(Messagemsg){ ...... switch(msg.what){ ...... casePAUSE_ACTIVITY: handlePauseActivity((IBinder)msg.obj, false,msg.arg1!= 0,msg.arg2); maybeSnapshot(); break; ...... } ...... } ...... } 这里调用ActivityThread.handlePauseActivity进一步操作,msg.obj是一个ActivityRecord对象的引用,它代表的是Launcher这个Activity。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/965996,如需转载请自行联系原作者

优秀的个人博客,低调大师

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了。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/965990,如需转载请自行联系原作者

优秀的个人博客,低调大师

cocos2d-x自制工具06:AnimatePacker源代码

想不到的是,最近还有一些同行找我要AnimatePacker的古老代码。甚至提出了购买等方式。 这个工具的代码,之前私下里曾赠送了一些朋友,既然之前都没有收费,那么之后也不应该收费。我也从来没有想过用这个软件进行牟利。国内程序界很乱,不是什么东西都能拿钱买,也不是什么东西都能卖钱。 请使用Qt4.8的版本打开,这样可以方便编译。 Qt5调整了架构和4.x的工程存在兼容问题,需要修改才能编译。 代码很短,也没有经过修订和重构,其中的一些写法是不值得提倡的(包括渲染简单用画布做了一下)。唯一觉得不错的地方是,这是一个超轻量级的工具,没有破坏任何引擎代码,做了最小额度的封装,这种思路很有趣。 附件:http://down.51cto.com/data/2363883 本文转自 老G 51CTO博客,原文链接:http://blog.51cto.com/goldlion/1341740,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序安装过程源代码分析(4)

Step 12.PackageManagerService.scanPackageLI 这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中: [java] view plain copy classPackageManagerServiceextendsIPackageManager.Stub{ ...... //KeysareString(packagename),valuesarePackage.Thisalsoserves //asthelockfortheglobalstate.Methodsthatmustbecalledwith //thislockheldhavetheprefix"LP". finalHashMap<String,PackageParser.Package>mPackages= newHashMap<String,PackageParser.Package>(); ...... //Allavailableactivities,foryourresolvingpleasure. finalActivityIntentResolvermActivities= newActivityIntentResolver(); //Allavailablereceivers,foryourresolvingpleasure. finalActivityIntentResolvermReceivers= newActivityIntentResolver(); //Allavailableservices,foryourresolvingpleasure. finalServiceIntentResolvermServices=newServiceIntentResolver(); //KeysareString(providerclassname),valuesareProvider. finalHashMap<ComponentName,PackageParser.Provider>mProvidersByComponent= newHashMap<ComponentName,PackageParser.Provider>(); ...... privatePackageParser.PackagescanPackageLI(PackageParser.Packagepkg, intparseFlags,intscanMode,longcurrentTime){ ...... synchronized(mPackages){ ...... //AddthenewsettingtomPackages mPackages.put(pkg.applicationInfo.packageName,pkg); ...... intN=pkg.providers.size(); inti; for(i=0;i<N;i++){ PackageParser.Providerp=pkg.providers.get(i); p.info.processName=fixProcessName(pkg.applicationInfo.processName, p.info.processName,pkg.applicationInfo.uid); mProvidersByComponent.put(newComponentName(p.info.packageName, p.info.name),p); ...... } N=pkg.services.size(); for(i=0;i<N;i++){ PackageParser.Services=pkg.services.get(i); s.info.processName=fixProcessName(pkg.applicationInfo.processName, s.info.processName,pkg.applicationInfo.uid); mServices.addService(s); ...... } N=pkg.receivers.size(); r=null; for(i=0;i<N;i++){ PackageParser.Activitya=pkg.receivers.get(i); a.info.processName=fixProcessName(pkg.applicationInfo.processName, a.info.processName,pkg.applicationInfo.uid); mReceivers.addActivity(a,"receiver"); ...... } N=pkg.activities.size(); for(i=0;i<N;i++){ PackageParser.Activitya=pkg.activities.get(i); a.info.processName=fixProcessName(pkg.applicationInfo.processName, a.info.processName,pkg.applicationInfo.uid); mActivities.addActivity(a,"activity"); ...... } ...... } ...... returnpkg; } ...... } 这个函数主要就是把前面解析应用程序得到的package、provider、service、receiver和activity等信息保存在PackageManagerService服务中了。 这样,在Android系统启动的时候安装应用程序的过程就介绍完了,但是,这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了,在下一篇文章中,我们将介绍Launcher是如何启动的以及它是如何从PackageManagerService服务中把系统中已经安装好的应用程序展现出来的,敬请期待。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966524,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序安装过程源代码分析(2)

Step 4. AndroidRuntime.callStatic 这个函数定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中: [cpp] view plain copy /* *CallastaticJavaProgrammingLanguagefunctionthattakesnoargumentsandreturnsvoid. */ status_tAndroidRuntime::callStatic(constchar*className,constchar*methodName) { JNIEnv*env; jclassclazz; jmethodIDmethodId; env=getJNIEnv(); if(env==NULL) returnUNKNOWN_ERROR; clazz=findClass(env,className); if(clazz==NULL){ LOGE("ERROR:couldnotfindclass'%s'\n",className); returnUNKNOWN_ERROR; } methodId=env->GetStaticMethodID(clazz,methodName,"()V"); if(methodId==NULL){ LOGE("ERROR:couldnotfindmethod%s.%s\n",className,methodName); returnUNKNOWN_ERROR; } env->CallStaticVoidMethod(clazz,methodId); returnNO_ERROR; } 这个函数调用由参数className指定的java类的静态成员函数,这个静态成员函数是由参数methodName指定的。上面传进来的参数className的值为"com/android/server/SystemServer",而参数methodName的值为"init2",因此,接下来就会调用SystemServer类的init2函数了。 Step 5.SystemServer.init2 这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中: [java] view plain copy publicclassSystemServer { ...... publicstaticfinalvoidinit2(){ Slog.i(TAG,"EnteredtheAndroidsystemserver!"); Threadthr=newServerThread(); thr.setName("android.server.ServerThread"); thr.start(); } } 这个函数创建了一个ServerThread线程,PackageManagerService服务就是这个线程中启动的了。这里调用了ServerThread实例thr的start函数之后,下面就会执行这个实例的run函数了。 Step 6.ServerThread.run 这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中: [java] view plain copy classServerThreadextendsThread{ ...... @Override publicvoidrun(){ ...... IPackageManagerpm=null; ...... //Criticalservices... try{ ...... Slog.i(TAG,"PackageManager"); pm=PackageManagerService.main(context, factoryTest!=SystemServer.FACTORY_TEST_OFF); ...... }catch(RuntimeExceptione){ Slog.e("System","Failurestartingcoreservice",e); } ...... } ...... } 这个函数除了启动PackageManagerService服务之外,还启动了其它很多的服务,例如在前面学习Activity和Service的几篇文章中经常看到的ActivityManagerService服务,有兴趣的读者可以自己研究一下。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966521,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android应用程序启动过程源代码分析(4)

Step 28. ActivityStack.realStartActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中: publicclassActivityStack{ ...... finalbooleanrealStartActivityLocked(ActivityRecordr, ProcessRecordapp,booleanandResume,booleancheckConfig) throwsRemoteException{ ...... r.app=app; ...... intidx=app.activities.indexOf(r); if(idx<0){ app.activities.add(r); } ...... try{ ...... List<ResultInfo>results=null; List<Intent>newIntents=null; if(andResume){ results=r.results; newIntents=r.newIntents; } ...... app.thread.scheduleLaunchActivity(newIntent(r.intent),r, System.identityHashCode(r), r.info,r.icicle,results,newIntents,!andResume, mService.isNextTransitionForward()); ...... }catch(RemoteExceptione){ ...... } ...... returntrue; } ...... } 这里最终通过app.thread进入到ApplicationThreadProxy的scheduleLaunchActivity函数中,注意,这里的第二个参数r,是一个ActivityRecord类型的Binder对象,用来作来这个Activity的token值。 Step 29.ApplicationThreadProxy.scheduleLaunchActivity 这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中: classApplicationThreadProxyimplementsIApplicationThread{ ...... publicfinalvoidscheduleLaunchActivity(Intentintent,IBindertoken,intident, ActivityInfoinfo,Bundlestate,List<ResultInfo>pendingResults, List<Intent>pendingNewIntents,booleannotResumed,booleanisForward) throwsRemoteException{ Parceldata=Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); intent.writeToParcel(data,0); data.writeStrongBinder(token); data.writeInt(ident); info.writeToParcel(data,0); data.writeBundle(state); data.writeTypedList(pendingResults); data.writeTypedList(pendingNewIntents); data.writeInt(notResumed?1:0); data.writeInt(isForward?1:0); mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION,data,null, IBinder.FLAG_ONEWAY); data.recycle(); } ...... } 这个函数最终通过Binder驱动程序进入到ApplicationThread的scheduleLaunchActivity函数中。 Step 30.ApplicationThread.scheduleLaunchActivity 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中: publicfinalclassActivityThread{ ...... privatefinalclassApplicationThreadextendsApplicationThreadNative{ ...... //weusetokentoidentifythisactivitywithouthavingtosendthe //activityitselfbacktotheactivitymanager.(mattersmorewithipc) publicfinalvoidscheduleLaunchActivity(Intentintent,IBindertoken,intident, ActivityInfoinfo,Bundlestate,List<ResultInfo>pendingResults, List<Intent>pendingNewIntents,booleannotResumed,booleanisForward){ ActivityClientRecordr=newActivityClientRecord(); r.token=token; r.ident=ident; r.intent=intent; r.activityInfo=info; r.state=state; r.pendingResults=pendingResults; r.pendingIntents=pendingNewIntents; r.startsNotResumed=notResumed; r.isForward=isForward; queueOrSendMessage(H.LAUNCH_ACTIVITY,r); } ...... } ...... } 函数首先创建一个ActivityClientRecord实例,并且初始化它的成员变量,然后调用ActivityThread类的queueOrSendMessage函数进一步处理。 Step 31.ActivityThread.queueOrSendMessage 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中: publicfinalclassActivityThread{ ...... privatefinalclassApplicationThreadextendsApplicationThreadNative{ ...... //ifthethreadhasn'tstartedyet,wedon'thavethehandler,sojust //savethemessagesuntilwe'reready. privatefinalvoidqueueOrSendMessage(intwhat,Objectobj){ queueOrSendMessage(what,obj,0,0); } ...... privatefinalvoidqueueOrSendMessage(intwhat,Objectobj,intarg1,intarg2){ synchronized(this){ ...... Messagemsg=Message.obtain(); msg.what=what; msg.obj=obj; msg.arg1=arg1; msg.arg2=arg2; mH.sendMessage(msg); } } ...... } ...... } 函数把消息内容放在msg中,然后通过mH把消息分发出去,这里的成员变量mH我们在前面已经见过,消息分发出去后,最后会调用H类的handleMessage函数。 Step 32. H.handleMessage 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中: publicfinalclassActivityThread{ ...... privatefinalclassHextendsHandler{ ...... publicvoidhandleMessage(Messagemsg){ ...... switch(msg.what){ caseLAUNCH_ACTIVITY:{ ActivityClientRecordr=(ActivityClientRecord)msg.obj; r.packageInfo=getPackageInfoNoCheck( r.activityInfo.applicationInfo); handleLaunchActivity(r,null); }break; ...... } ...... } ...... } 这里最后调用ActivityThread类的handleLaunchActivity函数进一步处理。 Step 33.ActivityThread.handleLaunchActivity 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中: publicfinalclassActivityThread{ ...... privatefinalvoidhandleLaunchActivity(ActivityClientRecordr,IntentcustomIntent){ ...... Activitya=performLaunchActivity(r,customIntent); if(a!=null){ r.createdConfig=newConfiguration(mConfiguration); BundleoldState=r.state; handleResumeActivity(r.token,false,r.isForward); ...... }else{ ...... } } ...... } 这里首先调用performLaunchActivity函数来加载这个Activity类,即shy.luo.activity.MainActivity,然后调用它的onCreate函数,最后回到handleLaunchActivity函数时,再调用handleResumeActivity函数来使这个Activity进入Resumed状态,即会调用这个Activity的onResume函数,这是遵循Activity的生命周期的。 Step 34.ActivityThread.performLaunchActivity 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中: publicfinalclassActivityThread{ ...... privatefinalActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){ ActivityInfoaInfo=r.activityInfo; if(r.packageInfo==null){ r.packageInfo=getPackageInfo(aInfo.applicationInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentNamecomponent=r.intent.getComponent(); if(component==null){ component=r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if(r.activityInfo.targetActivity!=null){ component=newComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } Activityactivity=null; try{ java.lang.ClassLoadercl=r.packageInfo.getClassLoader(); activity=mInstrumentation.newActivity( cl,component.getClassName(),r.intent); r.intent.setExtrasClassLoader(cl); if(r.state!=null){ r.state.setClassLoader(cl); } }catch(Exceptione){ ...... } try{ Applicationapp=r.packageInfo.makeApplication(false,mInstrumentation); ...... if(activity!=null){ ContextImplappContext=newContextImpl(); appContext.init(r.packageInfo,r.token,this); appContext.setOuterContext(activity); CharSequencetitle=r.activityInfo.loadLabel(appContext.getPackageManager()); Configurationconfig=newConfiguration(mConfiguration); ...... activity.attach(appContext,this,getInstrumentation(),r.token, r.ident,app,r.intent,r.activityInfo,title,r.parent, r.embeddedID,r.lastNonConfigurationInstance, r.lastNonConfigurationChildInstances,config); if(customIntent!=null){ activity.mIntent=customIntent; } r.lastNonConfigurationInstance=null; r.lastNonConfigurationChildInstances=null; activity.mStartedActivity=false; inttheme=r.activityInfo.getThemeResource(); if(theme!=0){ activity.setTheme(theme); } activity.mCalled=false; mInstrumentation.callActivityOnCreate(activity,r.state); ...... r.activity=activity; r.stopped=true; if(!r.activity.mFinished){ activity.performStart(); r.stopped=false; } if(!r.activity.mFinished){ if(r.state!=null){ mInstrumentation.callActivityOnRestoreInstanceState(activity,r.state); } } if(!r.activity.mFinished){ activity.mCalled=false; mInstrumentation.callActivityOnPostCreate(activity,r.state); if(!activity.mCalled){ thrownewSuperNotCalledException( "Activity"+r.intent.getComponent().toShortString()+ "didnotcallthroughtosuper.onPostCreate()"); } } } r.paused=true; mActivities.put(r.token,r); }catch(SuperNotCalledExceptione){ ...... }catch(Exceptione){ ...... } returnactivity; } ...... } 函数前面是收集要启动的Activity的相关信息,主要package和component信息: ActivityInfoaInfo=r.activityInfo; if(r.packageInfo==null){ r.packageInfo=getPackageInfo(aInfo.applicationInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentNamecomponent=r.intent.getComponent(); if(component==null){ component=r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if(r.activityInfo.targetActivity!=null){ component=newComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } 然后通过ClassLoader将shy.luo.activity.MainActivity类加载进来: Activityactivity=null; try{ java.lang.ClassLoadercl=r.packageInfo.getClassLoader(); activity=mInstrumentation.newActivity( cl,component.getClassName(),r.intent); r.intent.setExtrasClassLoader(cl); if(r.state!=null){ r.state.setClassLoader(cl); } }catch(Exceptione){ ...... } 接下来是创建Application对象,这是根据AndroidManifest.xml配置文件中的Application标签的信息来创建的: Applicationapp=r.packageInfo.makeApplication(false,mInstrumentation); 后面的代码主要创建Activity的上下文信息,并通过attach方法将这些上下文信息设置到MainActivity中去: activity.attach(appContext,this,getInstrumentation(),r.token, r.ident,app,r.intent,r.activityInfo,title,r.parent, r.embeddedID,r.lastNonConfigurationInstance, r.lastNonConfigurationChildInstances,config); 最后还要调用MainActivity的onCreate函数: mInstrumentation.callActivityOnCreate(activity,r.state); 这里不是直接调用MainActivity的onCreate函数,而是通过mInstrumentation的callActivityOnCreate函数来间接调用,前面我们说过,mInstrumentation在这里的作用是监控Activity与系统的交互操作,相当于是系统运行日志。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/965992,如需转载请自行联系原作者

优秀的个人博客,低调大师

Git@OSC 项目推荐 — Spark 源代码注释与翻译

Spark是一个快速的、通用的大数据集群计算系统。 它提供了高层API接口(支持Scala,Java及Python)以及一个优化过的支持图计算和数据处理的引擎。 同时它也一些高级工具也提供了支持,包括对SQL及结构化数据处理的Spark SQL, 机器学习的MLLib, 图像处理的GraphX和实时流处理的Spark Streaming 文章转载自 开源中国社区 [http://www.oschina.net]

优秀的个人博客,低调大师

帮开发者“跨云”,IBM 开放 JumpGate 源代码

通过连接OpenStack和“其他的云”,IBM希望JumpGate能够成为OpenStack私有云和公共云之间的“时空门”。 JumpGate是IBM开发的用来解决云管理生态系统碎片化问题的中间件工具,用来吸引更多的云服务商支持OpenStack应用(即使他们没有部署OpenStack)。 IBM收购的SoftLyer的工程师Nathan Beittenmiller本周四在博客上发布了JumpGate,目的是为了防止云服务的碎片化危及OpenStack的未来。 过去两年IBM在OpenStack上投入大量资源,并围绕智能云项目开发出了大量OpenStack应用。 但是在2013年6月收购SoftLayer后,IBM面临一个尴尬的问题,作为OpenStack最大的支持者之一,因为IBM自己收购的云计算 技术公司SoftLayer使用的是自行开发的云控制层软件,并不支持OpenStack。为了解决这个问题,JumpGate应运而生。 JumpGate提供了一个轻量级的翻译层,可以实现OpenStack模块API与非OpenStack云服务之间的兼容性。这将为云服务商节省大量成本,并大大提高业界对OpenStack的支持。 JumpGate目前还处于早期的Alpha版本阶段,云服务商使用JumpGate前需要创建系统驱动,将OpenStack API语义映射到自己的API列表中。 更多信息可以访问JumpGate的GitHub网页。 文章来自IT经理网 文章转载自 开源中国社区 [http://www.oschina.net]

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册