Android8.1源码解析 – Android与Activity启动

广告位

闲来没事看看源码,于是写了这篇,本文主要介绍Android以及Activity的主要创建流程,所有流程基于An…

闲来没事看看源码,于是写了这篇,本文主要介绍Android以及Activity的主要创建流程,所有流程基于Android8.1的代码,在部分流程尤其是activity与之前版本存在较大差异,供大家参考。

一、Android启动流程

我们直接进到app_main.cpp进行查看了

int main(int argc, char* const argv[]){     runtime.start("com.android.internal.os.ZygoteInit", args, zygote); }  

AndroidRuntime.cpp

void AndroidRuntime::start(const char* className,                    const Vector<String8>& options, bool zygote){     if (startVm(&mJavaVM, &env, zygote) != 0) {         return;     }     onVmCreated(env); }  int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){     /*      * Register android functions.      */     if (startReg(env) < 0) {         ALOGE("Unable to register all android nativesn");         return;     } }  /*static*/ int AndroidRuntime::startReg(JNIEnv* env){     /*      * Every "register" function calls one or more things that return      * a local reference (e.g. FindClass).  Because we haven't really      * started the VM yet, they're all getting stored in the base frame      * and never released.  Use Push/Pop to manage the storage.      */     env->PushLocalFrame(200);      if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {         env->PopLocalFrame(NULL);         return -1;     }     env->PopLocalFrame(NULL); }  

gRegJNI注册了很多的函数:

static const RegJNIRec gRegJNI[] = {     REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit), //... }  

register_com_android_internal_os_ZygoteInit_nativeZygoteInit定义为:

int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env) {     const JNINativeMethod methods[] = {         { "nativeZygoteInit", "()V",             (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },     };     return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",         methods, NELEM(methods)); }  

终于看到ZygoteInit。进入看看:ZygoteInit.java

    public static void main(String argv[]) {             zygoteServer.registerServerSocket(socketName);             Runnable r = forkSystemServer(abiList, socketName, zygoteServer);             r.run();             // The select loop returns early in the child process after a fork and             // loops forever in the zygote.             caller = zygoteServer.runSelectLoop(abiList); }  

可知一共做了三件事:1)创建了一个socket接口,用来和ActivityManagerService通讯。
2)启动SystemServer组件。3)创建一个loop用来接听socket接口上ActivityManagerService的请求,来创建新的应用进程。

接着我们主要看一下SystemServer的流程:SystemServer.java

     /**      * The main entry point from zygote.      */     public static void main(String[] args) {         new SystemServer().run();     }  
private void run() {     // Ensure binder calls into the system always run at foreground priority.             BinderInternal.disableBackgroundScheduling(true);              // Increase the number of binder threads in system_server             BinderInternal.setMaxThreads(sMaxBinderThreads);//31              // Prepare the main looper thread (this thread).             android.os.Process.setThreadPriority(                 android.os.Process.THREAD_PRIORITY_FOREGROUND);//-2             android.os.Process.setCanSelfBackground(false);             Looper.prepareMainLooper();              // Initialize native services.             System.loadLibrary("android_servers");              // Check whether we failed to shut down last time we tried.             // This call may not return.             performPendingShutdown();              // Initialize the system context.             createSystemContext();              // Create the system service manager.             mSystemServiceManager = new SystemServiceManager(mSystemContext);             mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);             LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);             // Prepare the thread pool for init tasks that can be parallelized             SystemServerInitThreadPool.get();              // Start services.             startBootstrapServices();     /**      * Starts some essential services that are not tangled up in the bootstrap process.         */             startCoreServices();                 /**          * Starts a miscellaneous grab bag of stuff that has yet to be refactored       * and organized.          */             startOtherServices();             SystemServerInitThreadPool.shutdown();  }  

这里其实主要做了两件事情:1)createSystemContext进行了一些activity相关的配置。2)创建了很多service。下面先看第一个:

private void createSystemContext() {         ActivityThread activityThread = ActivityThread.systemMain();         mSystemContext = activityThread.getSystemContext();         mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);     }  
    public static ActivityThread systemMain() { //...         ActivityThread thread = new ActivityThread();         thread.attach(true);         return thread;     }      private void attach(boolean system) {//true         mInstrumentation = new Instrumentation();//新建Instrumentation         ContextImpl context = ContextImpl.createAppContext(                 this, getSystemContext().mPackageInfo);         mInitialApplication = context.mPackageInfo.makeApplication(true, null);//启动application         mInitialApplication.onCreate();     }  

可见,在此创建了Instrumentation、ContextImpl等工作。

接着看一下上面的service创建。从上面可见,SystemServer创建了SystemServiceManager,直接进行了初始化了很多service:

    startBootstrapServices();     startCoreServices();     startOtherServices();  

startBootstrapServices就是启动了最著名的ActivityManagerService(AMS),其中还有PowerManagerService、PackageManagerService:

private void startBootstrapServices() { // Activity manager runs the show.         traceBeginAndSlog("StartActivityManager");         mActivityManagerService = mSystemServiceManager.startService(                 ActivityManagerService.Lifecycle.class).getService();         mActivityManagerService.setSystemServiceManager(mSystemServiceManager);         mActivityManagerService.setInstaller(installer);         traceEnd();          mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);         mPackageManagerService = PackageManagerService.main(mSystemContext, installer,                 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); }  

可能也都看到了他们都是通过mSystemServiceManager创建的,为什么呢?其实是因为这些所有的service都是要注册在SystemServiceManager之中进行同意管理的。

public class SystemServiceManager {     private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();      public void startService(@NonNull final SystemService service) {         // Register it.         mServices.add(service);         // Start it.         service.onStart(); //... }  

上面的SystemServer.run()还有几个点需要关注一下:

    // maximum number of binder threads used for system_server     // will be higher than the system default     private static final int sMaxBinderThreads = 31;  
            // Ensure binder calls into the system always run at foreground priority.             BinderInternal.disableBackgroundScheduling(true);              // Increase the number of binder threads in system_server             BinderInternal.setMaxThreads(sMaxBinderThreads);  

binder进程的请求数量是在这里设置的默认为31,并且运行在foreground priority,同样SystemService进程优先级也是foreground priority且不可置为后台:

 android.os.Process.setThreadPriority(                 android.os.Process.THREAD_PRIORITY_FOREGROUND);//-2             android.os.Process.setCanSelfBackground(false);  

foreground priority在所有优先级中的位置:

public static final int THREAD_PRIORITY_AUDIO = -16; public static final int THREAD_PRIORITY_BACKGROUND = 10; public static final int THREAD_PRIORITY_DEFAULT = 0; public static final int THREAD_PRIORITY_DISPLAY = -4; public static final int THREAD_PRIORITY_FOREGROUND = -2; public static final int THREAD_PRIORITY_LESS_FAVORABLE = 1; public static final int THREAD_PRIORITY_LOWEST = 19; public static final int THREAD_PRIORITY_MORE_FAVORABLE = -1; public static final int THREAD_PRIORITY_URGENT_AUDIO = -19; public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8;  

平时我们使用的Activity在THREAD_PRIORITY_DEFAULT,Async在THREAD_PRIORITY_BACKGROUND。

OK,现在为止启动流程基本介绍完了。

二、Activity启动流程

让我们看一下activity启动流程,假设由桌面点击应用图标来启动:

Launcher.java

public void onClick(View v) boolean startActivitySafely(View v, Intent intent, Object tag) boolean startActivity(View v, Intent intent, Object tag) startActivity(intent);  

Activity.java

public void startActivity(Intent intent) public void startActivity(Intent intent, @Nullable Bundle options) public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,             @Nullable Bundle options)  

Instrumentation.java

public ActivityResult execStartActivity(             Context who, IBinder contextThread, IBinder token, Activity target,             Intent intent, int requestCode, Bundle options){     ActivityManager.getService()                 .startActivity(whoThread, who.getBasePackageName(), intent,                         intent.resolveTypeIfNeeded(who.getContentResolver()),                         token, target != null ? target.mEmbeddedID : null,                         requestCode, 0, null, options); }  

这里最终调用了ActivityManager的getService方法,从返回值IActivityManager就可以看出来应该是进行了跨进程通讯。

//ActivityManager.java     public static IActivityManager getService() {         return IActivityManagerSingleton.get();     }  
    private static final Singleton<IActivityManager> IActivityManagerSingleton =             new Singleton<IActivityManager>() {                 @Override                 protected IActivityManager create() {                     final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);                     final IActivityManager am = IActivityManager.Stub.asInterface(b);                     return am;                 }             };  

很明显这里是AIDL客户端调用,他的接口定义为:

//IActivityManager.aidl int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,             in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,             int flags, in ProfilerInfo profilerInfo, in Bundle options);  

想要继续根据我们的找到服务端的代码,这个服务端的代码其实并不是很好找的,这里我使用了全局搜索,最终中油一个调用点:ActivityManagerService.java(如果大家有好的查找方法,恳请告知,谢谢),找到了服务端代码下面的跟进就很方便了:

public class ActivityManagerService extends IActivityManager.Stub  public final int startActivity(IApplicationThread caller, String callingPackage,             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions)  

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

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)  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, WaitResult outResult,             Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,             TaskRecord inTask, String reason)  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, TaskRecord inTask, String reason)  private int startActivity(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, TaskRecord inTask)      private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,             int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,             ActivityRecord[] outActivity)      private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,             int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,             ActivityRecord[] outActivity)  

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

    boolean resumeFocusedStackTopActivityLocked(             ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {  

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

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options)      private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options)      final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,             ActivityRecord resuming, boolean pauseImmediately) {                 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,                         userLeaving, prev.configChangeFlags, pauseImmediately);     }  

跨进程通信
frameworks/base/core/java/android/app/ActivityThread.java

        public final void schedulePauseActivity(IBinder token, boolean finished,                 boolean userLeaving, int configChanges, boolean dontReport)          public void handleMessage(Message msg) {                 case PAUSE_ACTIVITY: {                     handlePauseActivity((IBinder) args.arg1, false,                             (args.argi1 & USER_LEAVING) != 0, args.argi2,                             (args.argi1 & DONT_REPORT) != 0, args.argi3);                 } break;          }      private void handlePauseActivity(IBinder token, boolean finished,             boolean userLeaving, int configChanges, boolean dontReport, int seq)  

跨进程通信
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final void activityPaused(IBinder token)  

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

final void activityPausedLocked(IBinder token, boolean timeout)   final void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,             boolean newTask, boolean keepCurTransition, ActivityOptions options)  

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

    private void completePauseLocked(boolean resumeNext, ActivityRecord resuming)  

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

    boolean resumeFocusedStackTopActivityLocked(             ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {  

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

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options)       private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options)  

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

    void startSpecificActivityLocked(ActivityRecord r,             boolean andResume, boolean checkConfig)  

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

    final ProcessRecord startProcessLocked(String processName,             ApplicationInfo info, boolean knownToBeDead, int intentFlags,             String hostingType, ComponentName hostingName, boolean allowWhileBooting,             boolean isolated, boolean keepIfLarge)      final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler)      private final void startProcessLocked(ProcessRecord app, String hostingType,             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {                 startResult = Process.start(entryPoint,                         app.processName, uid, uid, gids, debugFlags, mountExternal,                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,                         app.info.dataDir, invokeWith, entryPointArgs);     }  

frameworks/base/core/java/android/os/Process.java

zygoteProcess.start(processClass, niceName, uid, gid, gids,                     debugFlags, mountExternal, targetSdkVersion, seInfo,                     abi, instructionSet, appDataDir, invokeWith, zygoteArgs);  

产生了新的ActivityThread进程,然后执行进程的main方法。
frameworks/base/core/java/android/app/ActivityThread.java

 public static void main(String[] args) {         Looper.prepareMainLooper();          ActivityThread thread = new ActivityThread();         thread.attach(false);          if (sMainThreadHandler == null) {             sMainThreadHandler = thread.getHandler();         }          if (false) {             Looper.myLooper().setMessageLogging(new                     LogPrinter(Log.DEBUG, "ActivityThread"));         }          Looper.loop(); }  
private void attach(boolean system) {//false             final IActivityManager mgr = ActivityManager.getService();             mgr.attachApplication(mAppThread); }  

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

    public final void attachApplication(IApplicationThread thread)       private final boolean attachApplicationLocked(IApplicationThread thread,             int pid)   

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

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException       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,                         mergedConfiguration.getGlobalConfiguration(),                         mergedConfiguration.getOverrideConfiguration(), r.compat,                         r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,                         r.persistentState, results, newIntents, !andResume,                         mService.isNextTransitionForward(), profilerInfo);     }  

frameworks/base/core/java/android/app/ActivityThread.java$ApplicationThread

       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)           private void sendMessage(int what, Object obj)           public void handleMessage(Message msg) {                 case LAUNCH_ACTIVITY: {                     handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");                 } break;         }      private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason)       private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){         ContextImpl appContext = createBaseContextForActivity(r);         activity = mInstrumentation.newActivity(                     cl, component.getClassName(), r.intent)        Application app = r.packageInfo.makeApplication(false, mInstrumentation);         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, r.configCallback);         mInstrumentation.callActivityOnCreate(activity, r.state);     }      public void callActivityOnCreate(Activity activity, Bundle icicle) {         prePerformCreate(activity);         activity.performCreate(icicle);         postPerformCreate(activity);     }  

frameworks/base/core/java/android/app/Activity.java

    final void performCreate(Bundle icicle, PersistableBundle persistentState)       protected void onCreate(@Nullable Bundle savedInstanceState)   

最后,时序图先补一张以前版本的,最近补上。

Android8.1源码解析 - Android与Activity启动

自己是从事了七年开发的Android工程师,不少人私下问我,2019年Android进阶该怎么学,方法有没有?

没错,年初我花了一个多月的时间整理出来的学习资料,希望能帮助那些想进阶提升Android开发,却又不知道怎么进阶学习的朋友。【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!

Android8.1源码解析 - Android与Activity启动

点击链接加入群聊【Android移动架构总群】:加入群聊

Android8.1源码解析 - Android与Activity启动

资料大全

金罗老师

关于作者: 金罗老师

为您推荐

广告位

发表评论