Android深入四大组件一应用程序启动过程.docx

上传人:b****0 文档编号:17010931 上传时间:2023-07-21 格式:DOCX 页数:23 大小:122.08KB
下载 相关 举报
Android深入四大组件一应用程序启动过程.docx_第1页
第1页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第2页
第2页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第3页
第3页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第4页
第4页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第5页
第5页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第6页
第6页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第7页
第7页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第8页
第8页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第9页
第9页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第10页
第10页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第11页
第11页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第12页
第12页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第13页
第13页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第14页
第14页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第15页
第15页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第16页
第16页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第17页
第17页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第18页
第18页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第19页
第19页 / 共23页
Android深入四大组件一应用程序启动过程.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Android深入四大组件一应用程序启动过程.docx

《Android深入四大组件一应用程序启动过程.docx》由会员分享,可在线阅读,更多相关《Android深入四大组件一应用程序启动过程.docx(23页珍藏版)》请在冰点文库上搜索。

Android深入四大组件一应用程序启动过程.docx

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();

}

privatestaticfinalSingletongDefault=newSingleton(){

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

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2