Apprentissage du processus de démarrage de l'application Android

1. Organigramme de démarrage de l'application

La méthode est légèrement différente après la mise à jour d'Android. Voici le code source d'environ 8.

Veuillez ajouter une description de l'image

https://www.jianshu.com/p/538dcfac774d

Brève description:

  1. Lorsque vous cliquez sur l'icône de l'application de bureau, la méthode startActivity() du lanceur appelle la méthode startActivity de ActivityManagerService (AMS) dans le processus système via la communication Binder. pour démarrer l'application.

  2. Après avoir reçu la demande, le processus système (system_server) envoie une demande de création d'un processus d'application au processus Zygote.

  3. Le processus Zygote quitte le processus de candidature en fonction de la demande et exécute la méthode ActivityThread.main() de l'application. Au cours de ce processus, le thread principal de l'application initialise MainLooper et le gestionnaire de thread principal, et crée ApplicationThread pour la communication et la collaboration avec AMS.

  4. Le processus de candidature envoie une requête au processus du serveur_systèmeattachApplication via Binder. Il s'agit en fait du processus d'application appelant la méthode AMS dans le processus system_server via Binder, qui est utilisé pour lier l'objet à AMS. attachApplicationApplicationThread

  5. attachApplicationAprès avoir reçu la requête , le processus (utilisée pour créer une activité de démarrage). ) et la requête handleBindApplication au processus de candidature via Binder IPC (par exemple application d'initialisation et appelle la méthode system_server effectue un travail de préparation, puis envoie la requête onCreatescheduleLaunchActivity

  6. Après avoir reçu la demande, le thread Binder (ApplicationThread) du processus de candidature envoie BIND_APPLICATION et , puis interagissent via les messages du gestionnaire. LAUNCH_ACTIVITYApplicationThread

  7. Après avoir reçu le message, le thread principal créeApplication et appelle la méthode onCreate, puis crée l'activité cible via le mécanisme de réflexion et rappelle l'activité cible. Activités dans l'ordre. pour terminer le rendu de l'interface utilisateur et affiche l'interface principale de l'application. , , onCreate et autres méthodes. À ce stade, l'application est officiellement démarrée et entre dans le cycle de vie de l'activité, en exécutant les méthodes onCreateonStartonResume

2. Interprétation détaillée de l'organigramme

2.1. Fonctionnement du système

Veuillez ajouter une description de l'image

Incubation des processus Zygote

  • Avant le démarrage de l'application, le système démarre généralement le processus Zygote. Le processus Zygote préchargera certaines bibliothèques et ressources système en arrière-plan pour accélérer la création du processus.
  • Le processus Zygote exécute en interne la méthode main(), crée un environnement d'exécution Android et attend les requêtes des nouveaux processus d'application.

Ressources d'application et chargement de classe

  • Lorsque l'utilisateur démarre l'application ou déclenche d'autres composants de l'application, le processus Zygote charge les ressources de l'application (telles que les fichiers de mise en page, les ressources de chaîne, etc.) et les classes en fonction du nom du package de l'application.
  • Le processus Zygote servira de modèle pour le processus de candidature, chargeant le code et les ressources de l'application en fonction du nom du package de l'application et des ressources requises.

L'application affiche une fenêtre de lancement vide immédiatement après le lancement.

Qui a créé la fenêtre vide ? ?
Lors du processus de démarrage d'une application Android, cet arrière-plan éphémère est généralement automatiquement créé et géré par le système sans intervention directe du développeur. Plus précisément, la création et l'affichage de cet arrière-plan sont gérés par le service de gestion de fenêtres et la structure système du système Android.
Le système Android affiche cet arrière-plan lorsque l'application commence à fournir des commentaires utilisateur et à initialiser l'application en arrière-plan. Cet arrière-plan s'affiche avant que l'activité principale de l'application ne soit prête et commence à afficher l'interface utilisateur.
Les développeurs peuvent personnaliser cet arrière-plan éphémère en définissant le thème et l'écran de démarrage de l'application. Les thèmes et les écrans de démarrage font partie du processus d'apparence et de lancement de l'application, permettant aux développeurs de spécifier le logo, les couleurs, l'arrière-plan de l'application, etc. Les paramètres de thème et d'écran de démarrage de votre application peuvent être définis dans le fichier AndroidManifest.xml.
En résumé, cet arrière-plan éphémère est automatiquement créé et géré par le système Android pour fournir des commentaires aux utilisateurs et des transitions fluides de lancement des applications. Il n’oblige pas les développeurs à créer ou à exploiter directement.

Créer un processus de candidature

Processus de candidature :
Le processus de candidature est une unité d'exécution indépendante qui exécute des applications dans le système d'exploitation Android.
Chaque application s'exécute dans son propre processus d'application, ce qui signifie que chaque application dispose d'un espace mémoire indépendant, d'une machine virtuelle indépendante (Dalvik ou ART) et d'un environnement d'exécution indépendant. .
Le processus de candidature est responsable de l'exécution de divers composants de l'application, tels que l'activité, le service, le récepteur de diffusion, etc. Chaque composant s'exécute dans le cadre du processus de candidature.
Le cycle de vie du processus de candidature est géré par le système Android, et le système peut créer, détruire ou redémarrer le processus de candidature en cas de besoin.

2.2. Le processus démarre

Étape 3. ActivityThread est chargé en mémoire

ActivityThread.main() est appelé après la création du processus, mais il ne démarre pas l'activité immédiatement après la création du thread principal, mais continue de communiquer avec AMS.

https://www.cnblogs.com/mingfeng002/p/10323668.html

De plus, ActivityThread représente le thread principal d'Android dans Android, mais ce n'est pas une classe Thread.

À proprement parler, le fil principal de l'interface utilisateur n'est pas ActivityThread.
La classe ActivityThread est la classe initiale du processus Android APP, et sa fonction principale est l'entrée du processus APP.
Les segments de code d'exécution des événements d'interface utilisateur dans le processus APP sont fournis par ActivityThread.
En d'autres termes, l'instance Main Thread existe, mais le code qui la crée ne nous est pas visible. La fonction principale d'ActivityThread est exécutée dans ce fil principal.

Étape 3.2, ActivityThread.main()

public static void main(String[] args) {
    
    

    //各种初始化操作,省略
    
    
    //初始化主线程的Looper,一个线程只能有一个Looper
    Looper.prepareMainLooper();
    
    ActivityThread thread = new ActivityThread();
    //在attach方法中会完成Application对象的初始化,然后调用Application的onCreate()方法
    thread.attach(false, startSeq);
    
    if (sMainThreadHandler == null) {
    
    
        sMainThreadHandler = thread.getHandler();
    }
    //在主线程开启循环读取消息队列中的消息
    Looper.loop();
}
private void attach(boolean system, long startSeq) {
    
    
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
    
    
    	//如果应用进程
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                UserHandle.myUserId());
        //将mAppThread放到RuntimeInit类中的静态变量,也就是ApplicationThreadNative中的 this
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        //跨进程通讯,获取AMS在APP进程的代理
        final IActivityManager mgr = ActivityManager.getService();
        try {
    
    
            //将mAppThread传入ActivityManagerService中
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
    
    
            throw ex.rethrowFromSystemServer();
        }
        // 监听内存限制
        BinderInternal.addGcWatcher(new Runnable() {
    
    
            @Override public void run() {
    
    
                if (!mSomeActivitiesChanged) {
    
    
                    return;
                }
                Runtime runtime = Runtime.getRuntime();
                long dalvikMax = runtime.maxMemory();
                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                //当虚拟机已使用内存超过最大内存的四分之三时,ActivityTaskManager释放一些Activity
                if (dalvikUsed > ((3*dalvikMax)/4)) {
    
    
                    mSomeActivitiesChanged = false;
                    try {
    
    
                        ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
    
    
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        });
    } else {
    
    
        //通过system_server启动ActivityThread对象
        ...
    }
	// 为 ViewRootImpl 设置配置更新回调,
    ViewRootImpl.ConfigChangedCallback configChangedCallback
            = (Configuration globalConfig) -> {
    
    
        synchronized (mResourcesManager) {
    
    
            ....
        }
    };
    //添加配置回调
    ViewRootImpl.addConfigCallback(configChangedCallback);
}

Étape 4. ActivityManagerService.attachApplication()

7020      @Override
7021      public final void attachApplication(IApplicationThread thread) {
    
    
7022          synchronized (this) {
    
    
7023              int callingPid = Binder.getCallingPid();
7024              final long origId = Binder.clearCallingIdentity();
7025              attachApplicationLocked(thread, callingPid);
7026              Binder.restoreCallingIdentity(origId);
7027          }
7028      }
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    
    

	....
    
    //ApplicationThread调用bindApplication,ApplicationThread是ActivityThread的内部类
    thread.bindApplication(processName, appInfo, providerList,···);
    
	....
    
    //查看这个进程中是否有顶部可见的activity正在等待运行…(10以后的版本,之前跟这基本一致)
6955          // See if the top visible activity is waiting to run in this process...
6956          if (normalMode) {
    
    
6957              try {
    
    
6958                  if (mStackSupervisor.attachApplicationLocked(app)) {
    
    
6959                      didSomething = true;
6960                  }
6961              } catch (Exception e) {
    
    
6962                  Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6963                  badApp = true;
6964              }
6965          }

6967          // Find any services that should be running in this process...
6968          if (!badApp) {
    
    
6969              try {
    
    
6970                  didSomething |= mServices.attachApplicationLocked(app, processName);
6971                  checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6972              } catch (Exception e) {
    
    
6973                  Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6974                  badApp = true;
6975              }
6976          }
    ....
}

http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java#ApplicationThread

Étape 5.1

Comme ci-dessus

thread.bindApplication(processName, appInfo, providerList,···);

Le thread de la méthode est IApplicationThread, qui est l'agent d'ApplicationThread dans AMS.

Étape 6.1, ApplicationThread.bindApplication()

Envoyer un message bindApplication au gestionnaire d'ActivityThread

public final void bindApplication(String processName, ...
                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
    
    
    if (services != null) {
    
    
        ServiceManager.initServiceCache(services);
    }

    setCoreSettings(coreSettings);

    AppBindData data = new AppBindData();
    data.processName = processName;
	....
    sendMessage(H.BIND_APPLICATION, data);
}

Étape 7.1, ActivityThread.H reçoit

BIND_APPLICATION

Le gestionnaire reçoit le message et traite BindApplication

1658                  case BIND_APPLICATION:
1659                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1660                      AppBindData data = (AppBindData)msg.obj;
1661                      handleBindApplication(data);
1662                      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1663                      break;

Diverses initialisations, création d'instances d'application et appel de onCreate d'application

private void handleBindApplication(AppBindData data) {
    
    
    //在运行时将当前执行线程注册为敏感线程
    VMRuntime.registerSensitiveThread();
    ...
    //标记进程起始时间
    Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
    ...
    //设置进程名字
    Process.setArgV0(data.processName);
    
    //设置一个标记位,androidQ及以上版本一些不明确数组相关的类会抛出数组越界异常
    //例如[SparseArray的keyAt和setValueAt在Q之前的版本不会抛出异常](/https://blog.csdn.net/wzz18749670290/article/details/109352466)
    UtilConfig.setThrowExceptionForUpperArrayOutOfBounds(
                data.appInfo.targetSdkVersion >= Build.VERSION_CODES.Q);
    //androidP之前用BitmapFactory解码Bitmap,会放大density。android P及以后,用ImageDecoder解码Bitmap,会跳过upscale节约内存
    ImageDecoder.sApiLevel = data.appInfo.targetSdkVersion;
    
    //重置系统时区
    TimeZone.setDefault(null);
    //断点调试相关
    if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
    
    
        // XXX should have option to change the port.
        ...
    }
    ...
    //渲染调试相关
    boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
    HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
    HardwareRenderer.setPackageName(data.appInfo.packageName);
    
    //初始化HTTP代理
    final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
    if (b != null) {
    
    
        final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
        try {
    
    
            Proxy.setHttpProxySystemProperty(service.getProxyForNetwork(null));
        } catch (RemoteException e) {
    
    
            throw e.rethrowFromSystemServer();
        }
    }
    //创建Instrumentation并初始化
    // Continue loading instrumentation.
    if (ii != null) {
    
    
        ApplicationInfo instrApp;
        try {
    
    
            instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0,
                    UserHandle.myUserId());
        } catch (RemoteException e) {
    
    
            instrApp = null;
        }
        if (instrApp == null) {
    
    
            instrApp = new ApplicationInfo();
        }
        ii.copyTo(instrApp);
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false, true, false);

        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
                appContext.getOpPackageName());
        try {
    
    
            //通过ClassLoader创建Instrumentation
            final ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation)
                cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } catch (Exception e) {
    
    
           ...
        }
        //初始化Instrumentation
        final ComponentName component = new ComponentName(ii.packageName, ii.name);
        mInstrumentation.init(this, instrContext, appContext, component,
                data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
    } else {
    
    
        mInstrumentation = new Instrumentation();
        mInstrumentation.basicInit(this);
    }
    
    ...
    
    

    Application app;
    try {
    
    
        //创建application,这里面会调用application的attachBaseContext,这里的info对应的class是LoadedApk.java,最终也是通过classLoader创建Application
        app = data.info.makeApplication(data.restrictedBackupMode, null);
        ...
        if (!data.restrictedBackupMode) {
    
    
            if (!ArrayUtils.isEmpty(data.providers)) {
    
    
                //这里调用installProvider()->AppComponentFactory.instantiateProvider->
                //localProvider.attachInfo()->ContentProvider.onCreate();
                //看到这里就明白了为什么LeakCanary2.0不需要在Application中手动初始化
                installContentProviders(app, data.providers);
            }
        }
        
        //调用application的onCreate
        mInstrumentation.callApplicationOnCreate(app);
    }
    //预加载字体资源
    FontsContract.setApplicationContextForResources(appContext);
    ...
}

Avant mInstrumentation.newApplication, le contexte de l'application a été créé et la classe d'implémentation spécifique est ContextImpl.

Ensuite, le contexte est transmis lors de la création de l'application, c'est-à-dire que l'application contient le contexte.

Après avoir créé l'application, ContextImpl appelle setOuterContext(app), afin que le contexte contienne une référence à l'application. C'est pourquoi nous pouvons context.getApplicationContext()

LoadedApk.makeApplication()

http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/android/app/LoadedApk.java

554    public Application makeApplication(boolean forceDefaultAppClass,
555            Instrumentation instrumentation) {
    
    
556        if (mApplication != null) {
    
    
557            return mApplication;
558        }
559
560        Application app = null;
561
562        String appClass = mApplicationInfo.className;
563        if (forceDefaultAppClass || (appClass == null)) {
    
    
564            appClass = "android.app.Application";
565        }
566
567        try {
    
    
568            java.lang.ClassLoader cl = getClassLoader();
569            if (!mPackageName.equals("android")) {
    
    
570                initializeJavaContextClassLoader();
571            }
572            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
573            app = mActivityThread.mInstrumentation.newApplication(
574                    cl, appClass, appContext);
575            appContext.setOuterContext(app);
576        } catch (Exception e) {
    
    
577            if (!mActivityThread.mInstrumentation.onException(app, e)) {
    
    
578                throw new RuntimeException(
579                    "Unable to instantiate application " + appClass
580                    + ": " + e.toString(), e);
581            }
582        }
583        mActivityThread.mAllApplications.add(app);
584        mApplication = app;
585
586        if (instrumentation != null) {
    
    
587            try {
    
    
588                instrumentation.callApplicationOnCreate(app);
589            } catch (Exception e) {
    
    
590                if (!instrumentation.onException(app, e)) {
    
    
591                    throw new RuntimeException(
592                        "Unable to create application " + app.getClass().getName()
593                        + ": " + e.toString(), e);
594                }
595            }
596        }
597
598        // Rewrite the R 'constants' for all library apks.
599        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
600                .getAssignedPackageIdentifiers();
601        final int N = packageIdentifiers.size();
602        for (int i = 0; i < N; i++) {
    
    
603            final int id = packageIdentifiers.keyAt(i);
604            if (id == 0x01 || id == 0x7f) {
    
    
605                continue;
606            }
607
608            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
609        }
610
611        return app;
612    }
Instrumentation.newApplication()

http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/android/app/Instrumentation.java

public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    
    
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    //调用Application的attach    
    app.attach(context);
    return app;
}

public void callApplicationOnCreate(Application app) {
    
    
    //调用Application的onCreate   
    app.onCreate();
}

Étape 5.2,

(mStackSupervisor.attachApplicationLocked(app)) 

RéunionActivityStackSupervisorRéunion

http://aospxref.com/android-8.0.0_r36/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

957      boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    
    

    			....

972                              if (realStartActivityLocked(hr, app, true, true)) {
    
    
973                                  didSomething = true;
974                              }

				....

984          if (!didSomething) {
    
    
985              ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
986          }
987          return didSomething;
988      }
1325      final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
1326              boolean andResume, boolean checkConfig) throws RemoteException {
    
    
1327  		  //等到所有的onPause()方法执行结束才会去启动新的Activity
1328          if (!allPausedActivitiesComplete()) {
    
    
1335              return false;
1336          }
				
				....

1466  			//调用ApplicationThread的scheduleLaunchActivity用于启动一个Activity
1467              app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1468                      System.identityHashCode(r), r.info,
1469                      // TODO: Have this take the merged configuration instead of separate global and
1470                      // override configs.
1471                      mergedConfiguration.getGlobalConfiguration(),
1472                      mergedConfiguration.getOverrideConfiguration(), r.compat,
1473                      r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
1474                      r.persistentState, results, newIntents, !andResume,
1475                      mService.isNextTransitionForward(), profilerInfo);

				....

1548  
1549          return true;
1550      }

Étape 6.2, ApplicationThread.scheduleLaunchActivity()

748          // we use token to identify this activity without having to send the
749          // activity itself back to the activity manager. (matters more with ipc)
750          @Override
751          public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
752                  ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
753                  CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
754                  int procState, Bundle state, PersistableBundle persistentState,
755                  List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
756                  boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
    
    
757  
					....
				
783              sendMessage(H.LAUNCH_ACTIVITY, r);
784          }

Étape 7.2, ActivityThread.H reçoit

LANCEMENT_ACTIVITÉ
1584          public void handleMessage(Message msg) {
    
    
1585              if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1586              switch (msg.what) {
    
    
1587                  case LAUNCH_ACTIVITY: {
    
    
1588                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1589                      final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1590  
1591                      r.packageInfo = getPackageInfoNoCheck(
1592                              r.activityInfo.applicationInfo, r.compatInfo);
1593                      handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
1594                      Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1595                  } break;

Étape 8.2, handleLaunchActivity

2872      private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    
    

2874          //如果我们在进入后台后准备gc,那么我们回到活动状态,所以跳过它。
			
				....

2883          //确保我们正在运行最新的配置。

2889          // 创建活动之前进行初始化
2890          WindowManagerGlobal.initialize();
2891  
2892          Activity a = performLaunchActivity(r, customIntent);
2893  
				// 一些关于onResume还是finish的判断
2894          if (a != null) {
    
    
2895              r.createdConfig = new Configuration(mConfiguration);
2896              reportSizeConfigurations(r);
2897              Bundle oldState = r.state;

				// 这里会调用到 ActivityClientRecord.activity.performResume(),判断是否 onResume调用
2898              handleResumeActivity(r.token, false, r.isForward,
2899                      !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
2900  
2901              if (!r.activity.mFinished && r.startsNotResumed) {
    
    
2902                  // The activity manager actually wants this one to start out paused, because it
2903                  // needs to be visible but isn't in the foreground. We accomplish this by going
2904                  // through the normal startup (because activities expect to go through onResume()
2905                  // the first time they run, before their window is displayed), and then pausing it.
2906                  // However, in this case we do -not- need to do the full pause cycle (of freezing
2907                  // and such) because the activity manager assumes it can just retain the current
2908                  // state it has.
2909                  performPauseActivityIfNeeded(r, reason);
2910  
2911                  // We need to keep around the original state, in case we need to be created again.
2912                  // But we only do this for pre-Honeycomb apps, which always save their state when
2913                  // pausing, so we can not have them save their state when restarting from a paused
2914                  // state. For HC and later, we want to (and can) let the state be saved as the
2915                  // normal part of stopping the activity.
2916                  if (r.isPreHoneycomb()) {
    
    
2917                      r.state = oldState;
2918                  }
2919              }
2920          } else {
    
    
2921              // If there was an error, for any reason, tell the activity manager to stop us.
2922              try {
    
    
2923                  ActivityManager.getService()
2924                      .finishActivity(r.token, Activity.RESULT_CANCELED, null,
2925                              Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
2926              } catch (RemoteException ex) {
    
    
2927                  throw ex.rethrowFromSystemServer();
2928              }
2929          }
2930      }
performLaunchActivity
2683      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    
2684          // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2685  
				....
2703  
2704          ContextImpl appContext = createBaseContextForActivity(r);
2705          Activity activity = null;
2706          try {
    
    
				//通过Instrumentation反射获取Activity实例
2707              java.lang.ClassLoader cl = appContext.getClassLoader();
2708              activity = mInstrumentation.newActivity(
2709                      cl, component.getClassName(), r.intent);
2710              StrictMode.incrementExpectedActivityCount(activity.getClass());
2711              r.intent.setExtrasClassLoader(cl);
2712              r.intent.prepareToEnterProcess();
2713              if (r.state != null) {
    
    
2714                  r.state.setClassLoader(cl);
2715              }
2716          } catch (Exception e) {
    
    
2717              if (!mInstrumentation.onException(activity, e)) {
    
    
2718                  throw new RuntimeException(
2719                      "Unable to instantiate activity " + component
2720                      + ": " + e.toString(), e);
2721              }
2722          }
2723  
2724          try {
    
    
					//如果是多进程就创建,不是多进程就不创建
2725              Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2726  
				....
				
					//回调activity的attach方法
2749                  appContext.setOuterContext(activity);
2750                  activity.attach(appContext, this, getInstrumentation(), r.token,
2751                          r.ident, app, r.intent, r.activityInfo, title, r.parent,
2752                          r.embeddedID, r.lastNonConfigurationInstances, config,
2753                          r.referrer, r.voiceInteractor, window, r.configCallback);
2754  
2755                  if (customIntent != null) {
    
    
2756                      activity.mIntent = customIntent;
2757                  }

						....
						
						//设置主题
2761                  int theme = r.activityInfo.getThemeResource();
2762                  if (theme != 0) {
    
    
2763                      activity.setTheme(theme);
2764                  }
2765  
						//通过Instrumentation来回调activity的onCreate()方法
2766                  activity.mCalled = false;
2767                  if (r.isPersistable()) {
    
    
2768                      mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2769                  } else {
    
    
2770                      mInstrumentation.callActivityOnCreate(activity, r.state);
2771                  }
2772                  if (!activity.mCalled) {
    
    
2773                      throw new SuperNotCalledException(
2774                          "Activity " + r.intent.getComponent().toShortString() +
2775                          " did not call through to super.onCreate()");
2776                  }
2777                  r.activity = activity;
2778                  r.stopped = true;

						//start
2779                  if (!r.activity.mFinished) {
    
    
2780                      activity.performStart();
2781                      r.stopped = false;
2782                  }

						//RestoreInstanceState
2783                  if (!r.activity.mFinished) {
    
    
2784                      if (r.isPersistable()) {
    
    
2785                          if (r.state != null || r.persistentState != null) {
    
    
2786                              mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2787                                      r.persistentState);
2788                          }
2789                      } else if (r.state != null) {
    
    
2790                          mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2791                      }
2792                  }

						//OnPostCreate
2793                  if (!r.activity.mFinished) {
    
    
2794                      activity.mCalled = false;
2795                      if (r.isPersistable()) {
    
    
2796                          mInstrumentation.callActivityOnPostCreate(activity, r.state,
2797                                  r.persistentState);
2798                      } else {
    
    
2799                          mInstrumentation.callActivityOnPostCreate(activity, r.state);
2800                      }
2801                      if (!activity.mCalled) {
    
    
2802                          throw new SuperNotCalledException(
2803                              "Activity " + r.intent.getComponent().toShortString() +
2804                              " did not call through to super.onPostCreate()");
2805                      }
2806                  }
2807              }
2808              r.paused = true;
2809  				//加入mActivities Map统一管理
2810              mActivities.put(r.token, r);
2811  
2812          } catch (SuperNotCalledException e) {
    
    
2813              throw e;
2814  
2815          } catch (Exception e) {
    
    
2816              if (!mInstrumentation.onException(activity, e)) {
    
    
2817                  throw new RuntimeException(
2818                      "Unable to start activity " + component
2819                      + ": " + e.toString(), e);
2820              }
2821          }
2822  
2823          return activity;
2824      }

3. API

3.1、ActivityThread

http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/app/ActivityThread.java

Voici quelques méthodes de la classe ActivityThread dans Android 8 :

  1. main() : point d'entrée principal du processus de candidature, utilisé pour initialiser l'état global de l'application, y compris la création Application d'instances et démarrage du processus de candidature principal. Activité, traitement de la file d'attente des messages, etc.

  2. attach() : Attachez ActivityThread au processus de l'application pour l'initialisation et la gestion du cycle de vie de l'application.

  3. bindApplication() : lier l'application au processus de candidature, notamment en créant l'instance Application et en appelant son onCreate méthode , démarrez l’activité principale de l’application.

  4. schedulePauseActivity() : demande de suspendre le cycle de vie de l'activité spécifiée.

  5. scheduleStopActivity() : demande d'arrêter le cycle de vie de l'activité spécifiée.

  6. scheduleWindowVisibility() : gère les modifications de la visibilité de la fenêtre.

  7. scheduleLaunchActivity() : demandes de démarrage d'une nouvelle activité.

  8. scheduleReceiver() : gère l'enregistrement et la planification des récepteurs de diffusion.

  9. scheduleCreateService() : Demande de création d'un service.

  10. scheduleBindService() : demande de service de liaison.

  11. scheduleUnbindService() : demande de dissociation du service.

  12. scheduleServiceArgs() : transmet les paramètres au service.

  13. scheduleStopService() : Demande d'arrêt du service.

  14. scheduleRegisteredReceiver() : gère les récepteurs de diffusion enregistrés.

  15. scheduleLowMemory() : gère la situation de mémoire système insuffisante.

  16. dispatchPackageBroadcast() : distribue la diffusion du package d'application.

  17. dumpService() : afficher les informations sur le service.

  18. scheduleCrash() : le processus de demande de candidature est tombé en panne.

  19. dumpHeap() : sortie des informations de vidage du tas.

  20. attachAgent() : Agent attaché.

  21. setSchedulingGroup() : définit le groupe de planification.

  22. requestAssistContextExtras() : demande des informations contextuelles auxiliaires.

  23. updatePackageCompatibilityInfo() : met à jour les informations de compatibilité du package d'application.

  24. scheduleTrimMemory() : demande de réduction de la mémoire.

  25. scheduleOnNewActivityOptions() : notifie les nouvelles options d'activité.

Ces méthodes sont utilisées pour gérer le cycle de vie de l'application et gérer les messages et les événements afin de garantir que l'application peut démarrer, s'exécuter et répondre normalement aux opérations de l'utilisateur. Notez que ces méthodes peuvent changer entre les versions d'Android et qu'il peut exister d'autres méthodes privées qui implémentent de nouvelles fonctionnalités dans différentes versions. Si vous avez besoin de connaître la méthode ActivityThread pour une version spécifique d'Android, consultez le code source d'Android ou la documentation officielle de cette version.

3.2、ApplicationThread

Voici quelques méthodes de la classe ApplicationThread dans Android 8 :

  1. bindApplication() : utilisé pour lier l'application au processus de candidature. Cette méthode est responsable de la création d'une Application instance de l'application et de l'appel de sa méthode onCreate(), ainsi que du démarrage de l'activité principale de l'application.

  2. schedulePauseActivity() : demande de suspendre le cycle de vie de l'activité spécifiée.

  3. scheduleStopActivity() : demande d'arrêter le cycle de vie de l'activité spécifiée.

  4. scheduleWindowVisibility() : gère les modifications de la visibilité de la fenêtre.

  5. scheduleResumeActivity() : demandes de reprise du cycle de vie de l'activité spécifiée.

  6. scheduleSendResult() : utilisé pour envoyer les résultats de l'activité.

  7. scheduleLaunchActivity() : demandes de démarrage d'une nouvelle activité.

  8. scheduleCreateService() : Demande de création d'un service.

  9. scheduleBindService() : demande de service de liaison.

  10. scheduleUnbindService() : demande de dissociation du service.

  11. scheduleServiceArgs() : transmet les paramètres au service.

  12. scheduleStopService() : Demande d'arrêt du service.

  13. scheduleLowMemory() : gère la situation de mémoire système insuffisante.

  14. scheduleCrash() : le processus de demande de candidature est tombé en panne.

  15. dumpHeap() : utilisé pour afficher les informations de vidage du tas.

  16. dumpActivity() : utilisé pour afficher les informations sur l'activité.

  17. scheduleRegisteredReceiver() : gère les récepteurs de diffusion enregistrés.

  18. scheduleCreateBackupAgent() : utilisé pour demander la création d'un agent de sauvegarde, généralement appelé lorsque l'application a besoin de sauvegarder et de restaurer des données.

  19. scheduleDestroyBackupAgent() : utilisé pour demander la destruction de l'agent de sauvegarde, généralement appelé une fois l'opération de sauvegarde terminée.

  20. scheduleSuicide() : demande au processus de candidature de se suicider.

  21. scheduleConfigurationChanged() : utilisé pour gérer les modifications de configuration.

  22. scheduleSleeping() : utilisé pour gérer l'état de veille du processus de candidature.

  23. dispatchPackageBroadcast() : distribue la diffusion du package d'application.

  24. requestThumbnail() : Demande d'obtention de la vignette de l'activité.

  25. profilerControl() : utilisé pour le contrôle du profilage des performances.

Ces méthodes sont utilisées pour gérer le cycle de vie de l'application et gérer les messages et les événements afin de garantir que l'application peut démarrer, s'exécuter et répondre normalement aux opérations de l'utilisateur. Notez que ces méthodes peuvent changer entre les versions d'Android et qu'il peut exister d'autres méthodes privées qui implémentent de nouvelles fonctionnalités dans différentes versions. Si vous avez besoin de connaître la méthode ApplicationThread pour une version spécifique d'Android, consultez le code source d'Android ou la documentation officielle de cette version.

3.3、ActivityManagerService

ActivityManagerService:
http://aospxref.com/android-8.0.0_r36/xref/frameworks/base/services/core/java/com/android/server/am/ ActivityManagerService.java#attachApplicationLocked

3.4、ActivityStackSupervisor

ActivityStackSupervisor:
http://aospxref.com/android-8.0.0_r36/xref/frameworks/base/services/core/java/com/android/server/am/ ActivityStackSupervisor.java

Adresse de référence

La majeure partie de l'article est reproduite à partir de :
https://www.jianshu.com/p/643aa7c8e3dd

https://blog.csdn.net/sinat_31057219/article/details/132452043

https://blog.51cto.com/u_16213631/7298774

Analyse détaillée du processus de démarrage !!
https://blog.csdn.net/weixin_43093006/article/details/128699383

https://www.jianshu.com/p/538dcfac774d

Je suppose que tu aimes

Origine blog.csdn.net/weixin_35691921/article/details/116143407
conseillé
Classement