Android应用程序启动过程源代码分析.docx

上传人:b****7 文档编号:11389143 上传时间:2023-02-28 格式:DOCX 页数:46 大小:62.32KB
下载 相关 举报
Android应用程序启动过程源代码分析.docx_第1页
第1页 / 共46页
Android应用程序启动过程源代码分析.docx_第2页
第2页 / 共46页
Android应用程序启动过程源代码分析.docx_第3页
第3页 / 共46页
Android应用程序启动过程源代码分析.docx_第4页
第4页 / 共46页
Android应用程序启动过程源代码分析.docx_第5页
第5页 / 共46页
点击查看更多>>
下载资源
资源描述

Android应用程序启动过程源代码分析.docx

《Android应用程序启动过程源代码分析.docx》由会员分享,可在线阅读,更多相关《Android应用程序启动过程源代码分析.docx(46页珍藏版)》请在冰豆网上搜索。

Android应用程序启动过程源代码分析.docx

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

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

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1