Android 10.0 Activity的启动流程

Android 10.0 Activity的启动流程,第1张

本文主要学习记录,基于Android 10的源码,有错误欢迎指正,主要目的是梳理流程图。

进程为单位的调用栈图如下:

1activity中的startActivity方法最终都会通过拿到ATSM的代理IActivityTaskManager调用的startActivity;

2之后进入system server进程中的ATMS startActivity,ATMS 经过收集Intent信息,然后使用ActivityStackSupervisorstartSpecificActivityLocked,如果进程已经存在,则直接使用realStartActivityLocked,通过App的binder客户端的代理ApplicationThread调用回到bindApplication,走入Activity的启动流程;如果进程不存在则通过socket链接Zygote,请求fork新的进程;

3App进程创建完成后,进程启动会调用ActivityThreadmain方法,初始化主线程Handler,接着走入attach方法,然后通过AMS的代理调用AMS的attachApplication方法,并将App进程的通信代理ApplicationThread传入AMS;

4AMS获取到ATMS调用ApplicationThread的bindApplication回到App进程的ActivityThreadApplicationThreadbindApplication方法中,然后使用Handler切换到主线程执行handleBindApplication,这里初始化了App的进程名字、时间,用户的硬件配置,包括App的文件系统,创建了App的Context实例,Instrumentation实例,调用App的onCreate回调方法,同时告诉AMS APP初始化工作完毕;

5AMS接着会调用ATMS的attachApplication,最后调用ClientLifecycleManager的scheduleTransaction方法,通过App的Binder代理ApplicationThread回到ActivityThread;

6进入ActivityThreadApplicationThreadscheduleTransaction方法之后就进入了Activity的onStart、onResume回调

创建进程之前的过程主要是AMS的内部信息收集的判断的过程,下面主要看一下App进程启动的源码流程

从应用进程被创建开始,ActivityThreadmain被执行

调用ActivityThread的attach方法,然后将activity和AMS通信的Binder代理IApplicationThread实例传入AMS

接着进入AMS进程,ActivityManagerServiceattachApplicationLocked

1threadbindApplication :该方法主要讲App进程的配置信息通过IApplicationThread Binder通信回传到ActivityThread中

2mAtmInternalattachApplication :mAtmInternal实际就是ActivityTaskManager的实例,通过LocalServices加载

那么这里相当于走到了ActivityTaskManagerServer的attachApplication中

先看第一条:

注意:ActivityThread中存在于Binder通信的代理--》ApplicationThread extends IApplicationThreadStub

ActivityThread--》ApplicationThread--》bindApplication

这里的bindApplication主要初始化了AppBindData,然后发送BIND_APPLICATION给APP的主线程BIND_APPLICATION,最后执行了handleBindApplication

handleBindApplication如下:

ActivityThread--》class H extends Handler

该方法主要在App进程中对App的一些硬件资源配置申请的属性、App的文件夹等完成App基本信息的初始化

接着看第二条:mAtmInternalattachApplication

mAtmInternalattachApplication最终会调用mRootActivityContainerattachApplication(wpc)

RootActivityContainerattachApplication

接着调用ActivityStackSupervisorrealStartActivityLocked开始创建Activity

ActivityStackSupervisorrealStartActivityLocked

创建ClientLifecycleManager和ClientTransactionHandler来辅助管理Activity的生命周期

注意

clientTransactionaddCallback是LaunchActivityItem

lifecycleItem是ResumeActivityItem

ClientLifecycleManagerscheduleTransaction最终会调用ClientTransaction的schedule方法

那么这个mClient是IApplicationThread的实例,那么此时也就回到了ActivityThread的ApplicationThread中

ActivityThread的ApplicationThread中

因为ActivityThread继承ClientTransactionHandler,所以到了ClientTransactionHandler中

通过Handler发送消息EXECUTE_TRANSACTION到H中

接着TransactionExecutor的execute方法

LaunchActivityItemexecute方法

client其实是在ActivityThread的实例,那么就回到了ActivityThread的handleLaunchActivity

接着调用performLaunchActivity

在performLaunchActivity中,主要是加载App的资源包,然后创建了Activity的context实例,并创建了Activity的实例,接着调用activityattach方法,attach执行完之后调用了onCreate方法。

activityattach

activityattach中主要

1创建了PhoneWindow实例

2设置了Window接口的监听

3初始化了成员变量,包括线程和WindowManager

到此Oncreate已经完成,那么OnStart和OnResume去哪了?

TransactionExecutor的execute方法

之前们只分析了executeCallbacks,接着executeLifecycleState方法

TransactionExecutor的executeLifecycleState方法

cycleToPath:lifecycleItem即为ResumeActivityItem

第一点:

int finish = lifecycleItemgetTargetState()

lifecycleItem对应ResumeActivityItem,如下:

ResumeActivityItem的getTargetState方法

对应ActivityLifecycleItem中的枚举类型:

第二点:ActivityClientRecord中的mLifecycleState,由于在前面已经执行了handleLaunchActivity所以mLifecycleState=1

对应ActivityLifecycleItem中的枚举类型:

PRE_ON_CREATE = 0

所以final int star = 1

接着看getLifecyclePath,此时start=1,finish=3

那么返回的IntArray就是2

接着看performLifecycleSequence

最终执行的是handleStartActivity所以最终走到了ActivityThread的handleResumeActivity

两点:

调用activityperformStart

调用InstrumetationcallActivityOnPostCreate

performStart方法:

调用了InstrumentationcallActivityOnStart方法:

最终到了activity的onStart方法

第二点:InstrumentationcallActivityOnPostCreate

上面主要走了cycleToPath,接着ResumeActivityItemexecute

调用了handleResumeActivity方法

handleResumeActivity最终调用performResumeActivity

调用了InstrumentationcallActivityOnResume,

到了activityonResume()方法

参考文章: >

要启动一个新的Activity,我们可以通过调用Context中的startActivity来启动。像这样:

Intent intent = new Intent(this, ActivityDemoclass);

startActivity(intent); // ActivityDemo是需要启动的Activity类

通过上面的方法可以启动新的Activity了,但如果我要从当前的Activity中传递数据到新的Activity呢?很简单:Intent intent = new Intent(this,ActivityDemoclass);

Bundle bundle = new Bundle();

bundleputBoolean("bool_key", true);

intentputExtras(bundle);

startActivity(intent);

还有,有时候我们需要启动带返回值的Activity,简单的说就是需要新启动的Activity返回时将值传递给启动它的Activity,像这样:

Intent intent = new Intent(ActivityLifeDemothis,RevalueActivityclass);

startActivityForResult(intent, 0x1001);

ActivityLifeDemo是当前的Activity,启动RevalueActivity,我们在ActivityLifeDemo中需要获取RevalueActivity传回来的值。那么在RevalueActivity中就必须这样写:

Intent intent = new Intent();

intentputExtra("revalue_key","haha-revalueActivity");

setResult(0x1001, intent);

那么“revalue_key”值在哪里获取呢?必须重写onActivityResult方法,通过判断requestCode,来确定

if(requestCode==0x1001){

String str = datagetStringExtra("revalue_key");

Logi(TAG, "返回的值为:"+str);

}

1 从 Activity 本地调用startActivity()--> Activity#startActivityForResult()

2 Instrumentation #execStartActivity:Instrumentation类相当于一个管家,它的职责是管理各个应用程序和系统的交互,Activity都有此对象的实际引用,可以通过它监测系统与应用程序之间的所有交互。

3 ActivityManagerProxy #startActivity():发起了一次跨进程调用,ActivityManagerService是ActivityManagerNative的具体实现。

4 ActivityStarter ():主要负责处理Activity的Intent和Flags, 还有关联相关的Stack和TaskRecord。

ActivityStackstartActivityMayWait():获取Activity的启动信息,包括ResolveInfo和ActivityInfo,以及获取CallingPid和CallingUid;

ActivityStackstartActivityLocked():创建一个ActivityRecord;

ActivityStackstartActivityUnchecked():设置TaskRecord, 完成后执行ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked方法

5 ActivityStackSupervisor 和 ActivityStack :这里会判断进程是否存在和一些生命周期的方法

ActivityStackSupervisor#resumeFocusedStackTopActivityLocked()

  --> ActivityStackSupervisor#resumeTopActivityUncheckedLocked():

    --> ActivityStack#resumeTopActivityInnerLocked()

      --> ActivityStackSupervisor#startSpecificActivityLocked()

6: ApplicationThread :IApplicationThread的直接实现,发起了一次跨进程调用

7: ActivityThread :会调用sendMessage,最后调用到mHsendMessage(msg);

8: ActivityThread # performLaunchActivity ():会收集要启动的Activity的相关信息,主要是package和component信息,然后通过ClassLoader将要启动的Activity类加载出来。最后调用mInstrumentationcallActivityOnCreate()

9: Activity # performStart ():Activity的生命周期方法是通过Instrumentation类调用callActivityOnXXX方法最终调用Activity的onCreate等方法,调用时机为ActivityThread#performLaunchActivitiy()方法中。

一 应用程序的MainActivity通过Binder进程间通信机制通知ActivityManagerService,它要启动一个新的Activity;

二 ActivityManagerService通过Binder进程间通信机制通知MainActivity进入Paused状态;

三 MainActivity通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就准备要在MainActivity所在的进程和任务中启动新的Activity了;

四 ActivityManagerService通过Binder进程间通信机制通知MainActivity所在的ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动 *** 作了。

Instrumentation : 监控应用与系统相关的交互行为。

AMS :组件管理调度中心,什么都不干,但是什么都管。

ActivityStarter :处理Activity什么时候启动,怎么样启动相关问题,也就是处理Intent与Flag相关问题,平时提到的启动模式都可以在这里找到实现。

ActivityStackSupervisior :这个类的作用你从它的名字就可以看出来,它用来管理Stack和Task。

ActivityStack :用来管理栈里的Activity。

ActivityThread :最终干活的人,是ActivityThread的内部类,Activity、Service、BroadcastReceiver的启动、切换、调度等各种 *** 作都在这个类里完成。

当目标Activity所属的进程已创建,则下一步调用到ATscheduleResumeActivity;

当目标Activity所属的进程未创建,则先创建进程后,再调用ATscheduleLaunchActivity

将Window相应task移至顶部,并创建AppWindowToken对象

创建LoadedApk对象;

创建ComponentName对象;

获取ClassLoader;

创建目标Activity对象;

创建Application对象;

回调onCreate(),一般地该方法内执行setContentView() *** 作;

获取activity的WindowManager

把actvitity的decorview设置INVISIBLE添加上去addview->mWindowSessionaddToDisplay->WMSaddWindow

makeVisible

activityResumed

updateFocusedWindowLocked来更新聚焦窗口情况

AMS通过binder最终通知ApplicationThread,进而通知主线程,ActivityThread通过HhandleMessage()来控制Activity的生命周期。

    ActivityThreadhandleConfigurationChanged

    ApplicationonCreate

    ActivityonCreate

    ActivityonRestoreInstanceState

    ActivityonRestart

    ActivityonStart

    ActivityonResume

    ActivityonRestart

    ActivityonStart

    ActivityonResume

    ActivityonSaveInstanceState

    ActivityonPause

    ActivityonSaveInstanceState

    ActivityonStop

    trimApplications() kill空进程并且更新进程的Adj值

    ActivityonDestroy

    检查第一个没有结束的activity 如没有显示launcher

    ActivityonPause

    ActivityonNewIntent

    ActivityonRestart

    ActivityonStart

    ActivityonResume

一先理解栈的概念(放置Activity实例的容器)

1Task(线性表)

任务栈Task,用来放置Activity实例的容器,先进后出,主要有2个基本 *** 作:压栈和出栈,其所存放的Activity是不支持重新排序的, 只能根据压栈和出栈 *** 作更改Activity的顺序

2app启动时,系统会为它默认创建一个对应的Task,用来放置根Activity

ps: Activity之间可以相互启动,当前应用的Activity可以去启动其他应用的Activity(相机),那么就是说栈的功能可以把其它app的activity加入到自己app的栈里

所以Task可以理解为负责管理所有用到的Activity实例的栈,但是android50之后 跨进程调用activity,这个activity会被放入到一个新的栈中。

二启动模式(只能根据压栈和出栈 *** 作更改Activity的顺序,所以是启动模式是以哪种姿势入栈)

通过在AndroidManifest文件中的属性andorid:launchMode来设置或者通过Intent的flag来设置

1standard(常规姿势入栈)

默认模式。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。应用场景:绝大多数Activity。

2singleTop(栈顶复用姿势入栈)==FLAG_ACTIVITY_SINGLE_TOP

栈顶复用模式,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用 onNewIntent() 方法。避免栈顶的activity被重复的创建。应用场景:在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用singleTop,否则每次点击都会新建一个Activity。某个场景下连续快速点击,启动了两个Activity。如果这个时候待启动的Activity使用 singleTop模式也是可以避免这个Bug的。

3singleTask(栈内复用姿势入栈)==FLAG_ACTIVITY_CLEAR_TOP

栈内复用模式, activity只会在任务栈里面存在一个实例。如果要激活的activity,在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent() 方法,并且清空这个activity任务栈上面所有的activity( CLEAR_TOP回到栈顶 )。应用场景:大多数App的主页。对于大部分应用,当我们在主界面点击回退按钮的时候都是退出应用,那么当我们第一次进入主界面之后,主界面位于栈底,以后不管我们打开了多少个Activity,只要我们再次回到主界面,都应该使用将主界面Activity上所有的Activity移除的方式来让主界面Activity处于栈顶,而不是往栈顶新加一个主界面Activity的实例,通过这种方式能够保证退出应用时所有的Activity都能报销毁。

4singleInstance(不入栈)

单一实例模式,整个手机 *** 作系统里面只有一个实例存在。不同的应用去打开这个activity 共享公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。应用场景:呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。建议谨慎使用。

5FLAG_ACTIVITY_NO_HISTORY

Activity使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在Activity栈中。

1getTaskId();获取当前activity所处的栈

2同一个应用程序中的activity的亲和性一样(taskAffinity),也就是说 Actviitya intent时setFalg(IntentFLAG_ACTIVITY_NEW_TASK)到Activityb 但是Actviitya和Activityb 还是一个栈

在不同的应用中跳转才会创建新的Task。

3在Activity上下文之外启动Activity需要给Intent设置FLAG_ACTIVITY_NEW_TASK标志,不然会报异常。

四 FLAG_ACTIVITY_CLEAR_TASK(必须和FLAG_ACTIVITY_NEW_TASK一起使用)

清空栈内activity,只留下这个activity

在目的activity中获取intent启动源的名字的方法

1 先说在setClass启动一个Activity的方法吧:

Intent intent = new Intent();

intentsetClass(this, CreatePlaylistclass) //参数一为当前Package的context,t当前Activity的context就是this,其他Package可能用到createPackageContex()参数二为你要打开的Activity的类名

startActivity(intent);

2 通过Component Name来打开的方式

Intent intent = new Intent();

intentsetAction(IntentACTION_MAIN); //添加一些特性,具体可以查看Intent文档,相关属性的介绍

intentaddCategory(IntentCATEGORY_LAUNCHER);

intentsetFlags(IntentFLAG_ACTIVITY_NEW_TASK | IntentFLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

//通过Bundle向要打开的的Activity传递一些数据

Bundle bundle = new Bundle();

bundleputString("data", new String(" Hello World"));

intentputExtras(bundle);

intentsetComponent(new ComponentName(

new String("comandroidtestActivity"), new String("comandroidtestActivitytestActivity")));

startActivity(intent);

当一个应用程序的Activity很多的时候,为了更好的用户体验效果,就需要对Activity的显示顺序做一些人为控制,而不要使用Android自身的Activity的历史记录堆栈机制,此时常常需要知道上一个Activity是哪一个。具体做法思路就是通过Intent启动一个Activity时,把当前的Activity信息传递到下一个Activity中,当下一个Activity启动时,通过Intent获取传入的参数即可知道上一个Activity的信息。

以上就是关于Android 10.0 Activity的启动流程全部的内容,包括:Android 10.0 Activity的启动流程、关于安卓intent启动activity的几种情况、如何启动一个activity涉及到哪些方法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9778874.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存