Android深入四大组件一应用程序启动过程.docx
- 文档编号:17010931
- 上传时间:2023-07-21
- 格式:DOCX
- 页数:23
- 大小:122.08KB
Android深入四大组件一应用程序启动过程.docx
《Android深入四大组件一应用程序启动过程.docx》由会员分享,可在线阅读,更多相关《Android深入四大组件一应用程序启动过程.docx(23页珍藏版)》请在冰点文库上搜索。
Android深入四大组件一应用程序启动过程
Android深入四大组件
(一)应用程序启动过程
前言
在此前的文章中,我讲过了Android系统启动流程和Android应用进程启动过程,这一篇顺理成章来学习Android7.0的应用程序的启动过程。
分析应用程序的启动过程其实就是分析根Activity的启动过程。
1.Launcher请求ActivityManageService
Launcher启动后会将已安装应用程序的快捷图标显示到界面上,当我们点击应用程序的快捷图标时就会调用Launcher的startActivitySafely方法,如下所示。
packages/apps/Launcher3/src/com/android/launcher3/Launcher.Java
publicbooleanstartActivitySafely(Viewv,Intentintent,Objecttag){
...
try{
success=startActivity(v,intent,tag);
}catch(ActivityNotFoundExceptione){
Toast.makeText(this,R.string.activity_not_found,Toast.LENGTH_SHORT).show();
Log.e(TAG,"Unabletolaunch.tag="+tag+"intent="+intent,e);
}
returnsuccess;
}
startActivitySafely函数中主要就是调用了startActivity函数:
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
privatebooleanstartActivity(Viewv,Intentintent,Objecttag){
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//1
try{
...
if(user==null||user.equals(UserHandleCompat.myUserHandle())){
StrictMode.VmPolicyoldPolicy=StrictMode.getVmPolicy();
try{
StrictMode.setVmPolicy(newStrictMode.VmPolicy.Builder().detectAll()
.penaltyLog().build());
startActivity(intent,optsBundle);//2
}finally{
StrictMode.setVmPolicy(oldPolicy);
}
}else{
launcherApps.startActivityForProfile(intent.getComponent(),user,
intent.getSourceBounds(),optsBundle);
}
returntrue;
}catch(SecurityExceptione){
...
}
returnfalse;
}
在注释1处设置Flag为Intent.FLAG_ACTIVITY_NEW_TASK,这样根Activity会在新的任务栈中启动。
在注释2处调用了startActivity函数:
frameworks/base/core/java/android/app/Activity.java
Override
publicvoidstartActivity(Intentintent,@NullableBundleoptions){
if(options!
=null){
startActivityForResult(intent,-1,options);
}else{
startActivityForResult(intent,-1);
}
}
startActivity会调用startActivityForResult函数,其中第二个参数为-1,表示Launcher不需要知道Activity启动的结果,startActivityForResult函数的代码如下所示。
frameworks/base/core/java/android/app/Activity.java
publicvoidstartActivityForResult(@RequiresPermissionIntentintent,intrequestCode,
@NullableBundleoptions){
if(mParent==null){
Instrumentation.ActivityResultar=
mInstrumentation.execStartActivity(
this,mMainThread.getApplicationThread(),mToken,this,
intent,requestCode,options);
...
}else{
...
}
}
mParent是Activity类型的,表示当前Activity的父类。
因为目前根Activity还没有创建出来,因此,mParent==null成立。
接着调用Instrumentation的execStartActivity方法,Instrumentation主要用来监控应用程序和系统的交互,execStartActivity方法的代码如下所示。
frameworks/base/core/java/android/app/Instrumentation.java
publicActivityResultexecStartActivity(
Contextwho,IBindercontextThread,IBindertoken,Activitytarget,
Intentintent,intrequestCode,Bundleoptions){
...
try{
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
intresult=ActivityManagerNative.getDefault()
.startActivity(whoThread,who.getBasePackageName(),intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token,target!
=null?
target.mEmbeddedID:
null,
requestCode,0,null,options);
checkStartActivityResult(result,intent);
}catch(RemoteExceptione){
thrownewRuntimeException("Failurefromsystem",e);
}
returnnull;
}
首先会调用ActivityManagerNative的getDefault来获取ActivityManageService(以后简称为AMS)的代理对象,接着调用它的startActivity方法。
首先我们先来查看ActivityManagerNative的getDefault方法做了什么:
frameworks/base/core/java/android/app/ActivityManagerNative.java
staticpublicIActivityManagergetDefault(){
returngDefault.get();
}
privatestaticfinalSingleton
protectedIActivityManagercreate(){
IBinderb=ServiceManager.getService("activity");//1
if(false){
Log.v("ActivityManager","defaultservicebinder="+b);
}
IActivityManageram=asInterface(b);//2
if(false){
Log.v("ActivityManager","defaultservice="+am);
}
returnam;
}
};
}
getDefault方法调用了gDefault的get方法,我们接着往下看,gDefault是一个Singleton类。
注释1处得到名为”activity”的Service代理对象,也就是ActivityManagerService的代理对象。
接着在注释2处将它封装成ActivityManagerProxy(以后简称为AMP)类型对象,并将它保存到gDefault中,此后调用ActivityManagerNative的getDefault方法就会直接获得AMS的代理AMP对象。
回到Instrumentation类的execStartActivity方法中,从上面得知就是调用AMP的startActivity,其中AMP是ActivityManagerNative的内部类,代码如下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java
publicintstartActivity(IApplicationThreadcaller,StringcallingPackage,Intentintent,
StringresolvedType,IBinderresultTo,StringresultWho,intrequestCode,
intstartFlags,ProfilerInfoprofilerInfo,Bundleoptions)throwsRemoteException{
Parceldata=Parcel.obtain();
Parcelreply=Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller!
=null?
caller.asBinder():
null);
data.writeString(callingPackage);
intent.writeToParcel(data,0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if(profilerInfo!
=null){
data.writeInt
(1);
profilerInfo.writeToParcel(data,Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}else{
data.writeInt(0);
}
if(options!
=null){
data.writeInt
(1);
options.writeToParcel(data,0);
}else{
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION,data,reply,0);//1
reply.readException();
intresult=reply.readInt();
reply.recycle();
data.recycle();
returnresult;
}
首先会将传入的参数写入到Parcel类型的data中。
在注释1处通过IBinder对象mRemote想AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。
那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用ActivityManagerNative的onTransact方法中执行,如下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java
@Override
publicbooleanonTransact(intcode,Parceldata,Parcelreply,intflags)
throwsRemoteException{
switch(code){
caseSTART_ACTIVITY_TRANSACTION:
{
...
intresult=startActivity(app,callingPackage,intent,resolvedType,
resultTo,resultWho,requestCode,startFlags,profilerInfo,options);
reply.writeNoException();
reply.writeInt(result);
returntrue;
}
}
onTransact中会调用AMS的startActivity方法,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
publicfinalintstartActivity(IApplicationThreadcaller,StringcallingPackage,
Intentintent,StringresolvedType,IBinderresultTo,StringresultWho,intrequestCode,
intstartFlags,ProfilerInfoprofilerInfo,BundlebOptions){
returnstartActivityAsUser(caller,callingPackage,intent,resolvedType,resultTo,
resultWho,requestCode,startFlags,profilerInfo,bOptions,
UserHandle.getCallingUserId());
}
为了便于理解,给出Launcher到AMS调用过程的时序图。
2.ActivityManageService到ApplicationThread的调用流程
AMS的startActivity方法中return了startActivityAsUser方法:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
publicfinalintstartActivityAsUser(IApplicationThreadcaller,StringcallingPackage,
Intentintent,StringresolvedType,IBinderresultTo,StringresultWho,intrequestCode,
intstartFlags,ProfilerInfoprofilerInfo,BundlebOptions,intuserId){
enforceNotIsolatedCaller("startActivity");
userId=mUserController.handleIncomingUser(Binder.getCallingPid(),Binder.getCallingUid(),
userId,false,ALLOW_FULL_ONLY,"startActivity",null);
returnmActivityStarter.startActivityMayWait(caller,-1,callingPackage,intent,
resolvedType,null,null,resultTo,resultWho,requestCode,startFlags,
profilerInfo,null,null,bOptions,false,userId,null,null);
startActivityAsUser方法中又return了mActivityStarter的startActivityMayWait方法,代码如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
finalintstartActivityMayWait(IApplicationThreadcaller,intcallingUid,
StringcallingPackage,Intentintent,StringresolvedType,
IVoiceInteractionSessionvoiceSession,IVoiceInteractorvoiceInteractor,
IBinderresultTo,StringresultWho,intrequestCode,intstartFlags,
ProfilerInfoprofilerInfo,IActivityManager.WaitResultoutResult,Configurationconfig,
BundlebOptions,booleanignoreTargetSecurity,intuserId,
IActivityContaineriContainer,TaskRecordinTask){
...
intres=startActivityLocked(caller,intent,ephemeralIntent,resolvedType,
aInfo,rInfo,voiceSession,voiceInteractor,
resultTo,resultWho,requestCode,callingPid,
callingUid,callingPackage,realCallingPid,realCallingUid,startFlags,
options,ignoreTargetSecurity,componentSpecified,outRecord,container,
inTask);
...
returnres;
}
}
又调用了startActivityLocked方法,代码如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
finalintstartActivityLocked(IApplicationThreadcaller,Intentintent,IntentephemeralIntent,
StringresolvedType,ActivityInfoaInfo,ResolveInforInfo,
IVoiceInteractionSessionvoiceSession,IVoiceInteractorvoiceInteractor,
IBinderresultTo,StringresultWho,intrequestCode,intcallingPid,intcallingUid,
StringcallingPackage,intrealCallingPid,intrealCallingUid,intstartFlags,
ActivityOptionsoptions,booleanignoreTargetSecurity,booleancomponentSpecified,
ActivityRecord[]outActivity,ActivityStackSupervisor.ActivityContainercontainer,
TaskRecordinTask){
...
doPendingActivityLaunchesLocked(false);
...
returnerr;
}
startActivityLocked函数代码非常多,我们只需要关注doPendingActivityLaunchesLocked方法,代码如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
finalvoiddoPendingActivityLaunchesLocked(booleandoResume){
while(!
mPendingActivityLaunches.isEmpty()){
finalPendingActivityLaunchpal=mPendingActivityLaunches.remove(0);
finalbooleanresume=doResume&&mPendingActivityLaunches.isEmpty();
try{
finalintresult=startActivityUnchecked(
pal.r,pal.sourceRecord,null,null,pal.startFlags,resume,null,null);
postStartActivityUnchec
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 深入 四大 组件 应用程序 启动 过程