Android应用程序启动过程源代码分析.docx
- 文档编号:11389143
- 上传时间:2023-02-28
- 格式:DOCX
- 页数:46
- 大小:62.32KB
Android应用程序启动过程源代码分析.docx
《Android应用程序启动过程源代码分析.docx》由会员分享,可在线阅读,更多相关《Android应用程序启动过程源代码分析.docx(46页珍藏版)》请在冰豆网上搜索。
Android应用程序启动过程源代码分析
Android应用程序启动过程源代码分析
前文简要介绍了Android应用程序的Activity的启动过程。
在Android系统中,应用程序是由Activity组成的,因此,应用程序的启动过程实际上就是应用程序中的默认Activity的启动过程,本文将详细分析应用程序框架层的源代码,了解Android应用程序的启动过程。
在上一篇文章Android应用程序的Activity启动过程简要介绍和学习计划中,我们举例子说明了启动Android应用程序中的Activity的两种情景,其中,在手机屏幕中点击应用程序图标的情景就会引发Android应用程序中的默认Activity的启动,从而把应用程序启动起来。
这种启动方式的特点是会启动一个新的进程来加载相应的Activity。
这里,我们继续以这个例子为例来说明Android应用程序的启动过程,即MainActivity的启动过程。
MainActivity的启动过程如下图所示:
下面详细分析每一步是如何实现的。
Step1.Launcher.startActivitySafely
在Android系统中,应用程序是由Launcher启动起来的,其实,Launcher本身也是一个应用程序,其它的应用程序安装后,就会Launcher的界面上出现一个相应的图标,点击这个图标时,Launcher就会对应的应用程序启动起来。
Launcher的源代码工程在packages/apps/Launcher2目录下,负责启动其它应用程序的源代码实现在src/com/android/launcher2/Launcher.java文件中:
/**
*Defaultlauncherapplication.
*/
publicfinalclassLauncherextendsActivity
implementsView.OnClickListener,OnLongClickListener,LauncherModel.Callbacks,AllAppsView.Watcher{
......
/**
*Launchestheintentreferredbytheclickedshortcut.
*
*@paramvTheviewrepresentingtheclickedshortcut.
*/
publicvoidonClick(Viewv){
Objecttag=v.getTag();
if(taginstanceofShortcutInfo){
//Openshortcut
finalIntentintent=((ShortcutInfo)tag).intent;
int[]pos=newint[2];
v.getLocationOnScreen(pos);
intent.setSourceBounds(newRect(pos[0],pos[1],
pos[0]+v.getWidth(),pos[1]+v.getHeight()));
startActivitySafely(intent,tag);
}elseif(taginstanceofFolderInfo){
......
}elseif(v==mHandleView){
......
}
}
voidstartActivitySafely(Intentintent,Objecttag){
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try{
startActivity(intent);
}catch(ActivityNotFoundExceptione){
......
}catch(SecurityExceptione){
......
}
}
......
}
回忆一下前面一篇文章Android应用程序的Activity启动过程简要介绍和学习计划说到的应用程序Activity,它的默认Activity是MainActivity,这里是AndroidManifest.xml文件中配置的:
name=".MainActivity" android: label="@string/app_name"> name="android.intent.action.MAIN"/> name="android.intent.category.LAUNCHER"/> 因此,这里的intent包含的信息为: action="android.intent.action.Main",category="android.intent.category.LAUNCHER",cmp="shy.luo.activity/.MainActivity",表示它要启动的Activity为shy.luo.activity.MainActivity。 Intent.FLAG_ACTIVITY_NEW_TASK表示要在一个新的Task中启动这个Activity,注意,Task是Android系统中的概念,它不同于进程Process的概念。 简单地说,一个Task是一系列Activity的集合,这个集合是以堆栈的形式来组织的,遵循后进先出的原则。 事实上,Task是一个非常复杂的概念,有兴趣的读者可以到官网 Step2.Activity.startActivity 在Step1中,我们看到,Launcher继承于Activity类,而Activity类实现了startActivity函数,因此,这里就调用了Activity.startActivity函数,它实现在frameworks/base/core/java/android/app/Activity.java文件中: viewplain publicclassActivityextendsContextThemeWrapper implementsLayoutInflater.Factory, Window.Callback,KeyEvent.Callback, OnCreateContextMenuListener,ComponentCallbacks{ ...... @Override publicvoidstartActivity(Intentintent){ startActivityForResult(intent,-1); } ...... } 这个函数实现很简单,它调用startActivityForResult来进一步处理,第二个参数传入-1表示不需要这个Actvity结束后的返回结果。 Step3.Activity.startActivityForResult 这个函数也是实现在frameworks/base/core/java/android/app/Activity.java文件中: viewplain publicclassActivityextendsContextThemeWrapper implementsLayoutInflater.Factory, Window.Callback,KeyEvent.Callback, OnCreateContextMenuListener,ComponentCallbacks{ ...... publicvoidstartActivityForResult(Intentintent,intrequestCode){ if(mParent==null){ Instrumentation.ActivityResultar= mInstrumentation.execStartActivity( this,mMainThread.getApplicationThread(),mToken,this, intent,requestCode); ...... }else{ ...... } ...... } 这里的mInstrumentation是Activity类的成员变量,它的类型是Intrumentation,定义在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用来监控应用程序和系统的交互。 这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程,我们在Android系统在新进程中启动自定义服务过程(startService)的原理分析一文中已经介绍过了。 这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。 这里我们需注意的是,这里的mMainThread代表的是Launcher应用程序运行的进程。 这里的mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。 Step4.Instrumentation.execStartActivity 这个函数定义在frameworks/base/core/java/android/app/Instrumentation.java文件中: viewplain publicclassInstrumentation{ .... publicActivityResultexecStartActivity( Contextwho,IBindercontextThread,IBindertoken,Activitytarget, Intentintent,intrequestCode){ IApplicationThreadwhoThread=(IApplicationThread)contextThread; if(mActivityMonitors! =null){ ...... } try{ intresult=ActivityManagerNative.getDefault() .startActivity(whoThread,intent, intent.resolveTypeIfNeeded(who.getContentResolver()), null,0,token,target! =null? target.mEmbeddedID: null, requestCode,false,false); ...... }catch(RemoteExceptione){ } returnnull; } ..... } 这里的ActivityManagerNative.getDefault返回ActivityManagerService的远程接口,即ActivityManagerProxy接口,具体可以参考Android系统在新进程中启动自定义服务过程(startService)的原理分析一文。 这里的intent.resolveTypeIfNeeded返回这个intent的MIME类型,在这个例子中,没有AndroidManifest.xml设置MainActivity的MIME类型,因此,这里返回null。 这里的target不为null,但是target.mEmbddedID为null,我们不用关注。 Step5.ActivityManagerProxy.startActivity 这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中: viewplain classActivityManagerProxyimplementsIActivityManager { ..... publicintstartActivity(IApplicationThreadcaller,Intentintent, StringresolvedType,Uri[]grantedUriPermissions,intgrantedMode, IBinderresultTo,StringresultWho, intrequestCode,booleanonlyIfNeeded, booleandebug)throwsRemoteException{ Parceldata=Parcel.obtain(); Parcelreply=Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller! =null? caller.asBinder(): null); intent.writeToParcel(data,0); data.writeString(resolvedType); data.writeTypedArray(grantedUriPermissions,0); data.writeInt(grantedMode); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(onlyIfNeeded? 1: 0); data.writeInt(debug? 1: 0); mRemote.transact(START_ACTIVITY_TRANSACTION,data,reply,0); reply.readException(); intresult=reply.readInt(); reply.recycle(); data.recycle(); returnresult; } ...... } 这里的参数比较多,我们先整理一下。 从上面的调用可以知道,这里的参数resolvedType、grantedUriPermissions和resultWho均为null;参数caller为ApplicationThread类型的Binder实体;参数resultTo为一个Binder实体的远程接口,我们先不关注它;参数grantedMode为0,我们也先不关注它;参数requestCode为-1;参数onlyIfNeeded和debug均空false。 Step6.ActivityManagerService.startActivity 上一步Step5通过Binder驱动程序就进入到ActivityManagerService的startActivity函数来了,它定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中: viewplain publicfinalclassActivityManagerServiceextendsActivityManagerNative implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{ ...... publicfinalintstartActivity(IApplicationThreadcaller, Intentintent,StringresolvedType,Uri[]grantedUriPermissions, intgrantedMode,IBinderresultTo, StringresultWho,intrequestCode,booleanonlyIfNeeded, booleandebug){ returnmMainStack.startActivityMayWait(caller,intent,resolvedType, grantedUriPermissions,grantedMode,resultTo,resultWho, requestCode,onlyIfNeeded,debug,null,null); } ...... } 这里只是简单地将操作转发给成员变量mMainStack的startActivityMayWait函数,这里的mMainStack的类型为ActivityStack。 Step7.ActivityStack.startActivityMayWait 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中: viewplain publicclassActivityStack{ ...... finalintstartActivityMayWait(IApplicationThreadcaller, Intentintent,StringresolvedType,Uri[]grantedUriPermissions, intgrantedMode,IBinderresultTo, StringresultWho,intrequestCode,booleanonlyIfNeeded, booleandebug,WaitResultoutResult,Configurationconfig){ ...... booleancomponentSpecified=intent.getComponent()! =null; //Don'tmodifytheclient'sobject! intent=newIntent(intent); //CollectinformationaboutthetargetoftheIntent. ActivityInfoaInfo; try{ ResolveInforInfo= AppGlobals.getPackageManager().resolveIntent( intent,resolvedType, PackageManager.MATCH_DEFAULT_ONLY |ActivityManagerService.STOCK_PM_FLAGS); aInfo=rInfo! =null? rInfo.activityInfo: null; }catch(RemoteExceptione){ ...... } if(aInfo! =null){ //Storethefoundtargetbackintotheintent,becausenowthat //wehaveitweneverwanttodothisagain.Forexample,ifthe //usernavigatesbacktothispointinthehistory,weshould //alwaysrestarttheexactsameactivity. intent.setComponent(newComponentName( aInfo.applicationInfo.packageName,aInfo.name)); ...... } synchronized(mService){ intcallingPid; intcallingUid; if(caller==null){ ...... }else{ callingPid=callingUid=-1; } mConfigWillChange=config! =null &&mService.mConfiguration.diff(config)! =0; ...... if(mMainStack&&aInfo! =null&& (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE)! =0){ ...... } intres=startActivityLocked(caller,intent,resolvedType, grantedUriPermissions,grantedMode,aInfo, resultTo,resultWho,requestCode,callingPid,callingUid, onlyIfNeeded,componentSpecified); if(mConfigWillChange&&mMainStack){ ...... } ...... if(outResult! =null){ ...... } returnres; } } ...... } 注意,从Step6传下来的参数outResult和config均为null,此外,表达式(aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE)! =0为false,因此,这里忽略了无关代码。 下面语句对参数intent的内容进行解析,得到MainActivity的相关信息,保存在aInfo变量中: viewplain ActivityInfoaInfo; try{ ResolveInforInfo= AppGlobals.getPackageManager().resolveIntent( intent,resolvedType, PackageManager.MATCH_DEFAULT_O
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 应用程序 启动 过程 源代码 分析