tiger_Activity启动流程

Activity启动流程

基于Android 11 源码分析

Android 7.0及以前采用代理模式,8.0及以后采用AIDL,ActivityManagerNative类被弃用,代理类ActivityManagerProxy已经被删除。

Android 11 使用了事务的方法进行整个流程的执行。

目录

文章目录


Activity界面: ####

1、Activity界面结构: #####

每一个Activity上面都有一个Window,可以通过getWindow获取
当setContentView设置显示后会回调Activity的onContentChanged方法

图片: https://uploader.shimo.im/f/epdisAy6aznwhv5E.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

2、Android界面关系: #####

图片: https://uploader.shimo.im/f/aozogypPkzJszKs4.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

Window 类 位于 /frameworks/base/core/java/android/view/Window.java。该类是一个抽象类,提供了绘制窗口的一组通用API。可以将之理解为一个载体,各种View在这个载体上显示。它的唯一实现类则是PhoneWindow。

PhoneWindow类 位于/frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindow.java。该类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。 简而言之,PhoneWindow类是把一个FrameLayout类即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的窗口操作接口。

DecorView类 该类是PhoneWindow类的内部类。该类继承FrameLayout,就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。DecorView则是由PhoneWindow负责添加。

打个比喻,Window类相当于一幅画(抽象概念,什么画我们未知) ,PhoneWindow为一副齐白石先生的山水画(具体概念,我们知道了是谁的、什么性质的画),DecorView则为该山水画的具体内容(有山、有水、有树,各种界面)。DecorView则呈现在PhoneWindow上。

3、Activity中Window创建过程: #####

图片: https://uploader.shimo.im/f/75CUEpIIjhs0ZIfh.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

Activity数据结构: ####

一、Activity中的关键数据结构: #####

1、数据结构类型: ######

ActivityRecord:Activity管理的最小单位,它一般对应一个用户界面。它需要记录AndroidManifest.xml中所定义的Activity的静态特征,同时也需要记录Activity在调度时的状态变化。ActivityRecord中的大部分成员变量都是记录Activity的相关信息成员变量final IApplicationToken.Stub appToken;可以看做是连接系统进程和应用进程的桥梁。
ActivityClientRecord:与ActivityRecord是在服务端(AMS)的记录相对应,是Activity在客户端(ActivityThread)的记录;
TaskRecord:它的职责就是管理ActivityRecord,记录activity开启的先后顺序。每个ActivityRecord都必须属于一个TaskRecord,TaskRecord与ActivityRecord是一对多的关系,栈顶的ActivityRecord表示当前用户可见的界面。TaskRecord中的成员变量final ArrayList mActivities;表示当前栈中管理的所有ActivityRecord。
ProcessRecord :记录着属于一个进程的所有ActivityRecord,运行在不同TaskRecord中的ActivityRecord可能属于同一个ProcessRecord。
ActivityStack:它的职责是管理TaskRecord。每个TaskRecord都必须属于一个ActivityStack,TaskRecord与ActivityStack是一对多的关系,栈顶的TaskRecord代表当前用户可见的任务。ActivityStack中的成员变量 private final ArrayList mTaskHistory = new ArrayList<>();表示当前栈中管理的所有TaskRecord。
ActivityDisplay:ActivityDisplay表示一个屏幕,Android支持三种屏幕:主屏幕,外接屏幕(HDMI等),虚拟屏幕(投屏)。一般情况下,即只有主屏幕时,ActivityStackSupervisor与ActivityDisplay都是系统唯一。
ActivityStackSupervisor:管理多个ActvityStack。

2、数据结构之间的关系: ######

图片: https://uploader.shimo.im/f/h4QjZ8PyM5wrYMNN.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

Activity启动: ####

一、桌面点击启动Activity #####

首先Launcher进程向AMS请求创建根Activity,AMS会判断根Activity所需的应用程序进程是否存在并启动,如果不存在就会请求Zygote进程创建应用程序进程。应用程序进程启动后,AMS会请求应用程序进程创建并启动根Activity。

1、启动模型: ######

图片: https://uploader.shimo.im/f/rMFvcU937U4BmkVq.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

2、相关进程: ######

图片: https://uploader.shimo.im/f/uJFvnaFSqo4vQgfw.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

3、启动时序图(Android 8.0)(大图): ######

图片: https://uploader.shimo.im/f/Cu1wBOtvniHyKWX8.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

启动时序图(Android 11)(大图):

图片: https://uploader.shimo.im/f/suCrGBYxJQ2grQCT.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

二、涉及到的类:

Instrumentation:负责调用Activity和Application生命周期。
ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
ActivityThread:ActivityThread 运行在UI线程(主线程),App的真正入口。
ApplicationThread:继承IApplicationThread.Stub类,用来实现AMS和ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
IActivityManager:继承与IInterface接口,抽象出跨进程通信需要实现的功能。
ActivityStackSupervisor:负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈
ActivityManagerService:负责管理四大组件和进程,包括生命周期和状态切换。AMS因为要和ui交互,所以极其复杂,涉及window。

具体流程(源码分析): ####

一、Launcher进程阶段: #####

Launcher通知AMS要启动activity。

Launcher.startActivitySafely->Activity.startActivity->Instrumentation.execStartActivity()->IActivityManager.startActivity->AMS.startActivityLauncher。

启动Activity最终是调用Activity.startActivity()方法,并设置intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);在新的栈Task中启动这个Activity。

Launcher请求 AMS 的时序图:

图片: https://uploader.shimo.im/f/B7OZIL4a8103lrMY.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjQ0NjgzMDgsImZpbGVHVUlEIjoiMjVxNU1heWFaakZ6UkxxRCIsImlhdCI6MTY2NDQ2ODAwOCwiaXNzIjoidXBsb2FkZXJfYWNjZXNzX3Jlc291cmNlIiwidXNlcklkIjo1NTY4NDYyNH0.38BwwjiECBhAZ5tHWeDeitiuXkVQCQGJbNWPyi1YQXc

1、Launcher点击图标 ######

源码:packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

当我们点击应用程序的快捷图标时,就会调用 Launcher 的 startActivitySafely 方法,如下源码所示:

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
    ···
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  //1
    if (v != null) {
        intent.setSourceBounds(getViewBounds(v));
    }
    try {
        if (Utilities.ATLEAST_MARSHMALLOW
                && (item instanceof ShortcutInfo)
                && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                 || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                && !((ShortcutInfo) item).isPromise()) {
            // Shortcuts need some special checks due to legacy reasons.
            startShortcutIntentSafely(intent, optsBundle, item);
        } else if (user == null || user.equals(Process.myUserHandle())) {
            // Could be launching some bookkeeping activity
            startActivity(intent, optsBundle);
        } else {
            LauncherAppsCompat.getInstance(this).startActivityForProfile(
                    intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
        }
        return true;
    } catch (ActivityNotFoundException|SecurityException e) {
        Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
    }
    return false;
}

Launcher源码中可以看到启动Activity最终是调用Activity.startActivity()方法,并设置intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);在新的栈Task中启动这个Activity。

2、Activity: ######

源码:frameworks/base/core/java/android/app/Activity.java

Activity.startActivity方法最终调用startActivityForResult

// 源码 5643行
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {

if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}

在 startActivity 方法中调用 startActivityForResult 方法,它的第二个参数为 -1,表示 Launcher 不需要知道 Activity 启动的结果。


private Instrumentation mInstrumentation;

// 源码6030行
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
Uri referrer = onProvideReferrer();
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}

当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()去执行启动操作;mMainThread.getApplicationThread()返回ActivityThead应用主线程的内部类ApplicationThread;ApplicationThread实现了IApplicationThread.StubAIDL接口方法,是App主线程ActivityThead对外提供(这里指AMS等系统服务)的操作接口,由此实现AMS对App的操作。

3、Instrumentation: ######

源码:frameworks/base/core/java/android/app/Instrumentation.java

Instrumentation是App与ATMS沟通的桥梁,内部通过ActivityTaskManager调取ATMS服务中的方法。每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。

// 源码1690行
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    ···
    try {
          intent.migrateExtraStreamToClipData(who);
          intent.prepareToLeaveProcess(who);
          // 通过 ActivityTaskManager 调用 ATMS 的 startActivity 方法
          int result = ActivityTaskManager.getService().startActivity(whoThread,
                  who.getBasePackageName(), who.getAttributionTag(), intent,
                  intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
                  requestCode, 0, null, options);
          checkStartActivityResult(result, intent);
      } catch (RemoteException e) {
          throw new RuntimeException("Failure from system", e);
      }
      return null;
}

首先通过 ActivityTaskManager.getService()方法来获取 ATMS 的代理对象,接着调用 ATMS的 startActivity 方法。

4 、ActivityTaskManager获取ATMS服务启动 ######

源码:frameworks/base/core/java/android/app/ActivityTaskManager.java

// 源码149行
public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                //获取一个AMS的binder对象
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); 
                return am = IActivityTaskManager.Stub.asInterface(b);  
            }
        };

先通过ServiceManager.getService获取一个AMS的binder对象,然后调用IActivityManager.Stub.asInterface。这些操作的作用就是使用AIDL进行IPC,与AMS进行通信。

getService在Android 5.0 中是ActivityManagerNative.getDefault()
在Android 7.0中getService()是:ActivityManager.getService()在Android 9.0及以上版本则是:ActivityTaskManager.getService()

Android 7.0 及以前用 AMS 的代理对象 ActivityManagerProxy 来与 AMS 进行进程间通信,Android 8.0 去除了 ActivityManagerNative 的内部类 ActivityManagerProxy,代替它的是 IActivityManager,IActivityManager.java 类是由 AIDL 工具在编译时自动生成的,它是 AMS 在本地的代理。

二、AMS(SystemServer进程)阶段: #####

ActivityManagerService.startActivity->ActivityManagerService.startActivityAsUser->ActivityStackSupervisor.startActivityMayWait->ActivityStackSupervisor.startActivityLocked(检查有没有在AndroidManifest中注册)->ActivityStackSupervisor.startActivityUncheckedLocked->ActivityStack.startActivityLocked(判断是否需要创建一个新的任务来启动Activity)->ActivityStack.resumeTopActivityLocked(获取栈顶的activity,并通知Launcher应该pause掉这个Activity以便启动新的activity)->ActivityStack.startPausingLocked->ApplicationThreadProxy.schedulePauseActivity

1、ActivityTaskManagerService启动Activity ######

源码:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

ATMS中有mActivityStarter和mUserController两个变量,UserController用户系统多用户的管理以及权限的管理,ActivityStarter加载Activity的控制类。

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final ActivityStarter mActivityStarter;
final UserController mUserController;

//构造函数中
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
mUserController = new UserController(this);

// 源码1042行
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}

// 源码1077行
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller(“startActivityAsUser”);

      userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
              Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

      // TODO: Switch to user app stacks here.
      return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
              .setCaller(caller)
              .setCallingPackage(callingPackage)
              .setCallingFeatureId(callingFeatureId)
              .setResolvedType(resolvedType)
              .setResultTo(resultTo)
              .setResultWho(resultWho)
              .setRequestCode(requestCode)
              .setStartFlags(startFlags)
              .setProfilerInfo(profilerInfo)
              .setActivityOptions(bOptions)
              .setUserId(userId)
              // 调用 ActivityStarter 的 execute 方法
              .execute();

  }


}

在getActivityStartController方法中返回的ActivityStartController,然后调用obtainStarter获取ActivityStarter对象,ATMS 根据这个 UserId 来确定调用者的权限。

最后调用了 ActivityStarter 的 startActivityLocked 方法,startActivityLocked 方法的参数要比 startActivityAsUser 多几个,需要注意的是倒数第二个参数类型为 TaskRecord,代表启动的 Activity 所在的栈。最后一个参数"startActivityAsUser" 代表启动的理由。

2、ActivityStarter管理Activity启动 ######

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值