Android深入四大组件(一)应用程序启动过程(后篇)

刘望舒 等级 517 0 0
  • Android框架层
  • Android深入四大组件 categories:
  • Android框架层

本文首发于微信公众号「刘望舒」

1.ActivityManageService到ApplicationThread的调用流程

AMS的startActivity方法中return了startActivityAsUser方法:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

   @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        return mActivityStarter.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

   final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
            Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
      ...
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);

        ...
            return res;
        }
    }

又调用了startActivityLocked方法,代码如下所示。 frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

 final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
       ...

        doPendingActivityLaunchesLocked(false);

       ...
        return err;
    }

startActivityLocked函数代码非常多,我们只需要关注doPendingActivityLaunchesLocked方法,代码如下所示。 frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

 final void doPendingActivityLaunchesLocked(boolean doResume) {
        while (!mPendingActivityLaunches.isEmpty()) {
            final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
            final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
            try {
                final int result = startActivityUnchecked(
                        pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
                postStartActivityUncheckedProcessing(
                        pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord,
                        mTargetStack);
            } catch (Exception e) {
                Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
                pal.sendErrorResult(e.getMessage());
            }
        }
    }

接着又调用startActivityUnchecked方法: frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
      ...  
         mSupervisor.resumeFocusedStackTopActivityLocked();  
      ... 
        return START_SUCCESS;
    }

startActivityUnchecked方法中调用了ActivityStackSupervisor类型的mSupervisor的resumeFocusedStackTopActivityLocked方法,如下所示。 frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

 boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//1
        }
        return false;
    }

在注释1处又调用了ActivityStack类型mFocusedStack的resumeTopActivityUncheckedLocked方法: frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
        try {
           ...
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

紧接着查看ActivityStack的resumeTopActivityInnerLocked方法: frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
         if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true; 

resumeTopActivityInnerLocked方法代码非常多,我们只需要关注调用了ActivityStackSupervisor类型mStackSupervisor的startSpecificActivityLocked方法,代码如下所示。 frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

  void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        r.task.stack.setLaunchTime(r);
        if (app != null && app.thread != null) {//1
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);//2
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
        }
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

在注释1处如果当前Activity所在的Application运行的话,会执行注释2处的代码。realStartActivityLocked方法的代码如下所示。 frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

  final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
     ...
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

    ...      

        return true;
    }

这里的 app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。 讲到这里再给出ActivityManageService到ApplicationThread调用过程的时序图,如下图所示。

Android深入四大组件(一)应用程序启动过程(后篇)

2.ActivityThread启动Activity

Android应用程序进程启动过程(前篇)这篇文章中提到过ActivityThread,在应用程序进程启动时会创建ActivityThread实例。ActivityThread作为应用程序进程的核心类,它是如何启动应用程序(Activity)的呢?我们接着往下看。 根据上文接着查看ApplicationThread的scheduleLaunchActivity方法,代码如下所示。 frameworks/base/core/java/android/app/ActivityThread.java

        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
         updateProcessState(procState, false);
            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;
            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;
            r.startsNotResumed = notResumed;
            r.isForward = isForward;
            r.profilerInfo = profilerInfo;
            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecord ,sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去,sendMessage方法的代码如下所示。 frameworks/base/core/java/android/app/ActivityThread.java

  private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
     ...
        mH.sendMessage(msg);
    }

这里mH指的是H,它是ActivityThread的内部类并继承Handler,H的代码如下所示。 frameworks/base/core/java/android/app/ActivityThread.java

  private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
  ...
  public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);//2
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case RELAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    handleRelaunchActivity(r);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
              ...
  }     

查看H的handleMessage方法中对LAUNCH_ACTIVITY的处理,在注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。 在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord 的成员变量packageInfo 。应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件。 在注释3处调用handleLaunchActivity方法,代码如下所示。 frameworks/base/core/java/android/app/ActivityThread.java

  private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
      ...
        Activity a = performLaunchActivity(r, customIntent);//1
        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//2

            if (!r.activity.mFinished && r.startsNotResumed) {      
                performPauseActivityIfNeeded(r, reason);
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

注释1处的performLaunchActivity方法用来启动Activity ,注释2处的代码用来将Activity 的状态置为Resume。如果该Activity为null则会通知ActivityManager停止启动Activity。来查看performLaunchActivity方法做了什么: frameworks/base/core/java/android/app/ActivityThread.java

  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  ...
        ActivityInfo aInfo = r.activityInfo;//1
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);//2
        }
        ComponentName component = r.intent.getComponent();//3
      ...
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);//4
           ...
            }
        } catch (Exception e) {
         ...
        }
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);//5

        ...
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);//6
         ...
                }
                /**
                *7
                */
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);

              ...
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
        }
        return activity;
}        

注释1处用来获取ActivityInfo,在注释2处获取APK文件的描述类LoadedApk。注释3处获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。注释4处根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。注释5处用来创建Application,makeApplication方法内部会调用Application的onCreate方法。注释6处用来创建要启动Activity的上下文环境。注释7处调用Activity的attach方法初始化Activity,attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。注释8处会调用Instrumentation的callActivityOnCreate方法来启动Activity: frameworks/base/core/java/android/app/Instrumentation.java

   public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);//1
        postPerformCreate(activity);
    }

注释1处调用了Activity的performCreate方法,代码如下所示。 frameworks/base/core/java/android/app/Activity.java

  final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

performCreate方法中会调用Activity的onCreate方法,这样Activity就启动了,即应用程序就启动了。 应用程序启动过程就讲到这里,最后附上ActivityThread启动Activity的时序图。 Android深入四大组件(一)应用程序启动过程(后篇)

收藏
评论区

相关推荐

Android Activity生命周期,启动模式,启动过程详解
前言 接触过Android开发的同学都知道Activity,Activity作为Android四大组件之一,使用频率高。简单来说Activity提供了一个显示界面,让用户进行各种操作,本文主要分为以下三个部分:Activity的生命周期,启动模式,以及Activity的工作过程。文中大部分篇幅来自《Android开发艺术探索》一书,尽管想多以流程或图
Android中一个Activity关闭另一个Activity或者在一个Activity中关闭多个Activity
前言 最近项目中涉及需要在一个Activity中关闭另一个Activity或者在一个Activity中关闭多个Activity的需求,不涉及到应用的退出。自己首先想了一些方案,同时也查了一些方案,就各个方案比较下优劣。 方案一 广播的方式 这个是最容易想到的,同时也是网上提供最多的。 由于多个Activity要使用,关闭页面
Android通过URL打开Activity
关注公众号 QXF069 为每个 Activity 绑定一个 url 可以方便的让第三方 app 直接打开这些 Activity。也可以方便在 app 内部进行页面跳转,解耦。 背景 举一个常见的案例,假设我们有个产品 A,产品 A 包含 h5 网页端和客户端,当用户在手机打开我们的 h5 网页端的时候,我们会期望如果用户手机安装了我们的客户端,则直接打
Android Fragment生命周期
Fragment 是在 Android 3.0 中引入,用于解决不同屏幕分辨率的设备上 UI 显示、交互的问题。Fragment 有自己的布局,有自己的生命周期,有自己的事件响应。 但 Fragment 又是依赖于 Activity 存在的,你可以把多个 Fragment 嵌入到一个 Activity 中或者多个 Activity 重用一个 Fragmen
【Flutter实战】 路由管理
2.2 路由管理路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewController。所谓路由管理,就是管理页面之间如何跳转,通常也可被称为导航管理。Flutter中的路由管理和原生开发类似,无论是Android还是
Android四大组件与进程启动的关系
一. 概述Android系统将进程做得很友好的封装,对于上层app开发者来说进程几乎是透明的. 了解Android的朋友,一定知道Android四大组件,但对于进程可能会相对较陌生. 一个进程里面可以跑多个app, 一个app也可以跑在多个进程里,通过配置Android:process属性来决定所运行在哪个进程。再进一步进程是如何创建的, 可能很多人不知道f
Android深入理解Context(一)Context关联类和Application Context创建过程
Android框架层 Android深入理解Contextcategories: Android框架层本文首发于微信公众号「刘望舒」 前言Context也就是上下文对象,是Android较为常用的类,但是对于Context,很多人都停留在会用的阶段,这个系列会带大家从源码角度来分析Context,从而更加深入的理解它。<!more 1.Context概述Co
Android深入理解Context(二)Activity和Service的Context创建过程
Android框架层 Android深入理解Contextcategories: Android框架层本文首发于微信公众号「刘望舒」 前言上一篇文章我们学习了Context关联类和Application Context的创建过程,这一篇我们接着来学习Activity和Service的Context创建过程。需要注意的是,本篇的知识点会和深入理解四大组件系列的
Android深入四大组件(一)应用程序启动过程(前篇)
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「后厂技术官」 前言在此前的文章中,我讲过了Android系统启动流程和Android应用进程启动过程,这一篇顺理成章来学习Android 7.0的应用程序的启动过程。分析应用程序的启动过程其实就是分析根Activity的启动过程。<!more 1
Android深入四大组件(一)应用程序启动过程(后篇)
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 1.ActivityManageService到ApplicationThread的调用流程AMS的startActivity方法中return了startActivityAsUser方法:<!moreframeworks/base/s
Android深入四大组件(二)Service的启动过程
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读和这两篇文章。<!more 1.ContextImpl到Activi
Android深入四大组件(六)Android8.0 根Activity启动过程(前篇)
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言在几个月前我写了和这两篇文章,它们都是基于Android 7.0,当我开始阅读Android 8.0源码时发现应用程序(根Activity)启动过程照Android 7.0有了一些变化,因此又写下了本篇文章,本篇文章照此前的文章不仅
Android深入四大组件(七)Android8.0 根Activity启动过程(后篇)
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言在几个月前我写了和这两篇文章,它们都是基于Android 7.0,当我开始阅读Android 8.0源码时发现应用程序(根Activity)启动过程照Android 7.0有了一些变化,因此又写下了本篇文章,本篇文章照此前的文章不仅
Android解析ActivityManagerService(二)ActivityTask和Activity栈管理
Android框架层 Android系统服务 ActivityManagerService Android框架层本文首发于微信公众号「刘望舒」 前言关于AMS,原计划是只写一篇文章来介绍,但是AMS功能繁多,一篇文章的篇幅远远不够。这一篇我们接着来学习与AMS相关的ActivityTask和Activity栈管理。 1.ActivityStackActivi
Android包管理机制(五)APK是如何被解析的
Android框架层 Android包管理机制 Android框架层本文首发于微信公众号「刘望舒」 前言在本系列的前面文章中,我介绍了PackageInstaller的初始化和安装APK过程、PMS处理APK的安装和PMS的创建过程,这些文章中经常会涉及到一个类,那就是PackageParser,它用来在APK的安装过程中解析APK,那么APK是如何被解析的