?? Android 源碼解讀-應用是如何啟動的??

      網友投稿 947 2022-05-30

      前言

      作為多年的 Android 開發,寫了不少應用,但是一個App到底是怎么啟動起來的?你要說桌面點一下就啟動了,那也對。但是它的啟動過程呢?帶著這樣的疑問,咱們來一步步學習。

      Android 啟動過程

      一般在任何平臺上,都會逐步加載和執行以下組件:

      Boot loader

      U-boot (optional)

      Kernel

      Android

      前言

      作為多年的 Android 開發,寫了不少應用,但是一個App到底是怎么啟動起來的?你要說桌面點一下就啟動了,那也對。但是它的啟動過程呢?帶著這樣的疑問,咱們來一步步學習。

      Android 啟動過程

      一般在任何平臺上,都會逐步加載和執行以下組件:

      Boot loader

      U-boot (optional)

      Kernel

      Android

      Android進程有以下順序:

      Init

      Zygote

      System Server

      Service Manager

      Other Daemons and processes

      Applications

      具體情況如下圖,這兩幅圖結合起來比較有意思:

      Boot ROM:當電源按下時,引導芯片代碼會從預定義的地方(固化在ROM)開始執行,加載引導程序BootLoader到RAM,然后執行。(這一步由"芯片廠商"負責設計和實現)

      Boot ROM:當電源按下時,引導芯片代碼會從預定義的地方(固化在ROM)開始執行,加載引導程序BootLoader到RAM,然后執行。(這一步由"芯片廠商"負責設計和實現)

      ?? Android 源碼解讀-應用是如何啟動的??

      Boot loader:Bootloader開始執行,首先負責完成硬件的初始化,引導操作系統啟動。(這一步由"設備廠商"負責設計和實現)

      Boot loader:Bootloader開始執行,首先負責完成硬件的初始化,引導操作系統啟動。(這一步由"設備廠商"負責設計和實現)

      Kernel:Linux 內核是 Android 的核心,負責進程創建、進程間通信、設備驅動程序、文件系統管理等。 Android 在主流內核上應用自定義補丁來支持 Android 運行所需的某些功能,如喚醒鎖等。內核可以作為未壓縮圖像或壓縮圖像加載。在加載時,它掛載根文件系統(通常作為內核命令行參數傳遞)并啟動用戶空間中的第一個應用程序。(這一步則是Android內核開發過程中需要涉及的地方)

      Kernel:Linux 內核是 Android 的核心,負責進程創建、進程間通信、設備驅動程序、文件系統管理等。 Android 在主流內核上應用自定義補丁來支持 Android 運行所需的某些功能,如喚醒鎖等。內核可以作為未壓縮圖像或壓縮圖像加載。在加載時,它掛載根文件系統(通常作為內核命令行參數傳遞)并啟動用戶空間中的第一個應用程序。(這一步則是Android內核開發過程中需要涉及的地方)

      Android:Android系統以及各大Linux的發行版,他們的Linux內核部分啟動過程都是差不多的,他們之間最大的區別就在于init程序的不同,因為init程序決定了系統在啟動過程中,究竟會啟動哪些守護進程和服務,以及呈現出怎樣的一個用戶UI界面。

      Android:Android系統以及各大Linux的發行版,他們的Linux內核部分啟動過程都是差不多的,他們之間最大的區別就在于init程序的不同,因為init程序決定了系統在啟動過程中,究竟會啟動哪些守護進程和服務,以及呈現出怎樣的一個用戶UI界面。

      因此,init程序是分析Android啟動過程中最核心的程序。

      init 和 init.rc:啟動內核時執行的第一個用戶空間應用程序是位于根文件夾中的 init 可執行文件。該進程解析稱為"init.rc"腳本的啟動腳本。這是用一種專為 android 設計的語言編寫的,用于啟動所有必要的進程、守護程序和服務,以便 android 正常運行。它提供了各種類型的執行時間,例如 early-init、on-boot、on-post-fs 等。

      init 和 init.rc:啟動內核時執行的第一個用戶空間應用程序是位于根文件夾中的 init 可執行文件。該進程解析稱為"init.rc"腳本的啟動腳本。這是用一種專為 android 設計的語言編寫的,用于啟動所有必要的進程、守護程序和服務,以便 android 正常運行。它提供了各種類型的執行時間,例如 early-init、on-boot、on-post-fs 等。

      Demons and Services:init 進程創建了各種守護進程和進程,如 rild、vold、mediaserver、adb 等,每個進程負責自己的功能。這些進程的描述不在本文的范圍內。相反,我們將更多地討論"Zygote"進程。

      Demons and Services:init 進程創建了各種守護進程和進程,如 rild、vold、mediaserver、adb 等,每個進程負責自己的功能。這些進程的描述不在本文的范圍內。相反,我們將更多地討論"Zygote"進程。

      Service Manager:Service Manager進程 管理系統中運行的所有Service。創建的每個服務都會在此進程中注冊自己,并且此信息供其他進程/應用程序將來參考。

      Service Manager:Service Manager進程 管理系統中運行的所有Service。創建的每個服務都會在此進程中注冊自己,并且此信息供其他進程/應用程序將來參考。

      Zygote:Zygote 是啟動時創建的第一個 init 進程之一。術語"合子"是基于生物學"形成的初始細胞分裂產生后代"。類似地,"zygote in android"初始化 Dalivik VM(ART) 和 fork 以創建多個實例來支持每個 android 進程。它有助于在 VM 實例之間使用共享代碼,從而減少內存占用和加載時間,非常適合嵌入式系統。Zygote 除了在服務器套接字上安裝偵聽器外,還預加載了稍后在 Android 應用程序中使用的類和資源。完成后,系統服務器啟動。

      Zygote:Zygote 是啟動時創建的第一個 init 進程之一。術語"合子"是基于生物學"形成的初始細胞分裂產生后代"。類似地,"zygote in android"初始化 Dalivik VM(ART) 和 fork 以創建多個實例來支持每個 android 進程。它有助于在 VM 實例之間使用共享代碼,從而減少內存占用和加載時間,非常適合嵌入式系統。Zygote 除了在服務器套接字上安裝偵聽器外,還預加載了稍后在 Android 應用程序中使用的類和資源。完成后,系統服務器啟動。

      System Server:SystemServer 進程啟動 Android 中可用的所有服務。

      System Server:SystemServer 進程啟動 Android 中可用的所有服務。

      本文咱們重點從 init 開始到應用啟動。

      1、Zygote是什么

      在Android系統里面,zygote是一個進程的名字。Android是基于Linux System的,當你的手機開機的時候,Linux的內核加載完成之后就會啟動一個叫"init"的進程。在Linux System里面,所有的進程都是由init進程fork出來的,我們的zygote進程也不例外。

      Zygote是一個虛擬機進程,同時也是一個虛擬機實例的孵化器,每當系統要求執行一個Android應用程序,Zygote就會fork(分裂)出一個子進程來執行該應用程序。

      1.1 app_main.cpp

      frameworks/base/cmds/app_process/app_main.cpp

      在Zygote啟動后就會執行 app_main.cpp。不管是C/c++/java,他們的入口就是 main(),就跟看到 Activity 咱們直接找 onCreate() 方法一樣。

      1.1.1 main()

      int main(int argc, char* const argv[]) { ... //注釋1:初始化AppRuntime(AndroidRunTime) AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); ... // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; // Skip unused "parent dir" argument. while (i < argc) { const char* arg = argv[i++]; //注釋2:設置zygote模式 if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = ZYGOTE_NICE_NAME; } ... } Vector args; if (!className.isEmpty()) { ... } else { // 我們處于 zygote 模式。 maybeCreateDalvikCache(); // 注釋3:在 zygote 模式下,將參數傳遞給 ZygoteInit.main() 方法。 if (startSystemServer) { args.add(String8("start-system-server")); } //PROP_VALUE_MAX = 92; char prop[PROP_VALUE_MAX]; ... String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); for (; i < argc; ++i) { args.add(String8(argv[i])); } } if (zygote) { //注釋4:調用 AndroidRuntime.start() 方法 runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { ... } else { ... } }

      注釋1:初始化 AppRuntime ,其實就是 AndroidRuntime(ART)。

      注釋2:設置zygote模式。

      注釋3:將參數傳遞給 ZygoteInit.main() 方法。

      注釋4:啟動 ZygoteInit 。這里的 ZygoteInit 就是 zygote 進程的啟動類。這個下面講到。咱們先看看AndroidRuntime 的 start() 方法。

      1.2 AndroidRuntime.cpp

      frameworks/base/core/jni/AndroidRuntime.cpp

      Android 虛擬機

      1.2.1 start()

      /* * Start the Android runtime. This involves starting the virtual machine and calling the "static void main(String[] args)" method in the class named by "className". * * Passes the main function two arguments, the class name and the specified * options string. */ void AndroidRuntime::start(const char* className, const Vector& options, bool zygote) { ... JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; //注釋1:啟動虛擬機 if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) { return; } onVmCreated(env); //注釋2:注冊安卓功能(JNI) if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } ... strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); ... /* * 啟動虛擬機。 該線程成為VM的主線程,直到VM退出才會返回。 */ char* slashClassName = toSlashClassName(className != NULL ? className : ""); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ... } else { ... jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ... } else { //注釋3 env->CallStaticVoidMethod(startClass, startMeth, strArray); #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } } ... }

      注釋1:啟動VM(虛擬機)

      注釋2:注冊安卓功能(JNI)

      注釋3:使用JNI調用 Zygotelnit 的 main() 方法。這里的 Zygotelnit 是class文件,也就是說從這里開始就進入java領域嘍。

      JNI:連接 native(C/C++) 層 和 java 層的橋梁。

      1.3 ZygoteInit.java

      frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

      /** * zygote 進程的啟動類。 */ public class ZygoteInit { ... }

      這是 Zygote 進程的入口點。 它創建 Zygote 服務,加載資源,并處理與準備分叉到應用程序的過程相關的其他任務。

      1.3.1 main()

      @UnsupportedAppUsage public static void main(String[] argv) { ZygoteServer zygoteServer = null; try { ... boolean startSystemServer = false; //argv:用于指定 Zygote 配置的命令行參數。 ... if (!enableLazyPreload) { //注釋1:預加載資源。 preload(bootTimingsTraceLog); ... } ... //注釋2:創建Zygote 的 LocalServerSocket 。 zygoteServer = new ZygoteServer(isPrimaryZygote); if (startSystemServer) { //注釋3:開始fork我們的SystemServer進程。 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); ... } ... // 注釋4:zygote 永久循環。 caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { ... } finally { if (zygoteServer != null) { zygoteServer.closeServerSocket(); } } ... }

      注釋1:預加載資源。

      注釋2:創建Zygote 的 LocalServerSocket 。

      注釋3:開始 fork 我們的 SystemServer 進程。

      注釋4:zygote 永久循環。

      這里咱們看看 forkSystemServer() ;

      1.3.2 forkSystemServer()

      /** * Prepare the arguments and forks for the system server process. * * @return A {@code Runnable} that provides an entrypoint into system_server code in the child * process; {@code null} in the parent. */ private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { ... //命令行來啟動system server //ZygoteInit.main(String argv[])里面的argv 跟這個類似 String[] args = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023," + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT, "com.android.server.SystemServer", }; //處理與 zygote spawner 相關的 args 的參數解析。 ZygoteArguments parsedArgs; int pid; try { ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args); try { parsedArgs = ZygoteArguments.getInstance(commandBuffer); } catch (EOFException e) { throw new AssertionError("Unexpected argument error for forking system server", e); } commandBuffer.close(); ... //請求 fork system_server 進程 pid = Zygote.forkSystemServer( parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, null, parsedArgs.mPermittedCapabilities, parsedArgs.mEffectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* For child process */ if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } zygoteServer.closeServerSocket(); return handleSystemServerProcess(parsedArgs); } return null; }

      這里啟動了一個 system server 。下面咱們就看看他。

      2、SystemServer

      system server 也就是 SystemServer。SystemServer也是一個進程,包括ActivityTaskManagerService、ActivityManagerService、PackageManagerService、WindowManagerService等92種服務。

      Android Framework里面兩大非常重要的進程:

      system_server 進程。

      system_server 進程。

      Zygote 進程。

      Zygote 進程。

      2.1 SystemServer.java

      frameworks/base/services/java/com/android/server/SystemServer.java

      public final class SystemServer { ... }

      2.1.1 main()

      /** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); } public SystemServer() { // Check for factory test mode. mFactoryTestMode = FactoryTest.getMode(); ... }

      下面 咱們看看 run () 里面都用什么?

      2.1.2 run()

      private void run() { try { ... // 注釋1:加載動態庫libandroid_service.so。 System.loadLibrary("android_servers"); // 注釋2:創建系統上下文。 createSystemContext(); // 調用每個進程的主線模塊初始化。 ActivityThread.initializeMainlineModules(); // 注釋3:創建 SystemServiceManager。 mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // 為可并行化的 init 任務準備線程池 SystemServerInitThreadPool.start(); ... } finally { } // 注釋4:Start services。 try { //下面咱們看看這個三個方法啟動什么服務 startBootstrapServices(t); startCoreServices(t); startOtherServices(t); } catch (Throwable ex) { ... } finally { t.traceEnd(); // StartServices } ... // 注釋5:Loop 永久循環。 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }

      注釋1:加載動態庫libandroid_service.so。

      注釋2:創建系統上下文。

      注釋3:創建 SystemServiceManager。

      注釋4:啟動服務(startBootstrapServices、startCoreServices、startOtherServices)

      注釋5:Loop 永久循環。

      2.1.3 createSystemContext()

      private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); }

      初始化系統上下文對象mSystemContext,并設置默認的主題,mSystemContext實際上是一個Context(ContextImpl)對象。

      調用ActivityThread.systemMain()的時候,會調用ActivityThread.attach(true),而在attach()里面,則創建了Application對象,并調用了Application.onCreate()。

      2.1.4 startBootstrapServices()

      /** * 啟動系統引導服務,因為這些服務之間有復雜的相互依賴關系,所以都放在了這個方法里面。 */ private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) { ... final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig"; SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG); // PlatformCompat Service 由 ActivityManagerService, PackageManagerService 和 其他服務做使用 PlatformCompat platformCompat = new PlatformCompat(mSystemContext); ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat); ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE, new PlatformCompatNative(platformCompat)); AppCompatCallbacks.install(new long[0]); mSystemServiceManager.startService(FileIntegrityService.class); Installer installer = mSystemServiceManager.startService(Installer.class); mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class); startMemtrackProxyService(); // StartActivityManager ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); //初始化 ActivityManagerService mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); mDataLoaderManagerService = mSystemServiceManager.startService( DataLoaderManagerService.class); mIncrementalServiceHandle = startIncrementalService(); t.traceEnd(); //初始化PowerManagerService(電源服務),需要提前啟動,因為其他服務需要它。 mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); mSystemServiceManager.startService(ThermalManagerService.class); // 電源管理已經開啟,ActivityManagerService負責電源管理功能 mActivityManagerService.initPowerManagement(); mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class); ... mSystemServiceManager.startService(LightsService.class); // Package manager isn't started yet; need to use SysProp not hardware feature if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) { mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS); } // 初始化DisplayManagerService(顯示管理器) mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); // Start the package manager. try { mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); } finally { } // 現在PackageManagerService已經啟動,注冊 dex 加載報告器來捕獲系統服務加載的任何 dex 文件。 // 這些 dex 文件將由 BackgroundDexOptService 優化。 SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); ... //將AMS等添加到ServiceManager中 mActivityManagerService.setSystemProcess(); if (!mOnlyCore) { boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { } finally { } } } ... mSensorServiceStart = SystemServerInitThreadPool.submit(() -> { TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog(); startSensorService(); }, START_SENSOR_SERVICE); // startBootstrapServices }

      改動比較大的地方:

      ActivityTaskManagerService(ATMS):負責管理除Activity和進程,包括生命周期和狀態切換。

      ActivityTaskManagerService(ATMS):負責管理除Activity和進程,包括生命周期和狀態切換。

      ActivityManagerService(AMS):AMN的子類,負責管理三大組件(除Activity)和進程,包括生命周期和狀態切換。AMS因為要和ui交互,所以極其復雜,涉及window。

      ActivityManagerService(AMS):AMN的子類,負責管理三大組件(除Activity)和進程,包括生命周期和狀態切換。AMS因為要和ui交互,所以極其復雜,涉及window。

      ActivityTaskManagerService:把 Activity 相關的內容從 ActivityManagerService 剝離出來而產生的。

      PowerManagerService(PMS):電源管理服務。

      PackageManagerService(PKMS):包管理服務,不叫PMS是為了和電源管理服務區分開。

      2.1.5 startCoreServices()

      /** * 啟動核心服務。 */ private void startCoreServices(@NonNull TimingsTraceAndSlog t) { // Service for system config mSystemServiceManager.startService(SystemConfigService.class); // Tracks the battery level. Requires LightService. mSystemServiceManager.startService(BatteryService.class); ... mSystemServiceManager.startService(LooperStatsService.Lifecycle.class); mSystemServiceManager.startService(ROLLBACK_MANAGER_SERVICE_CLASS); mSystemServiceManager.startService(NativeTombstoneManagerService.class); mSystemServiceManager.startService(BugreportManagerService.class); mSystemServiceManager.startService(GpuService.class); // startCoreServices }

      2.1.6 startOtherServices()

      /** * 啟動其他服務。 */ private void startOtherServices(@NonNull TimingsTraceAndSlog t) { final Context context = mSystemContext; VibratorService vibrator = null; DynamicSystemService dynamicSystem = null; IStorageManager storageManager = null; NetworkManagementService networkManagement = null; IpSecService ipSecService = null; VpnManagerService vpnManager = null; VcnManagementService vcnManagement = null; NetworkStatsService networkStats = null; NetworkPolicyManagerService networkPolicy = null; NsdService serviceDiscovery = null; WindowManagerService wm = null; SerialService serial = null; NetworkTimeUpdateService networkTimeUpdater = null; InputManagerService inputManager = null; TelephonyRegistry telephonyRegistry = null; ConsumerIrService consumerIr = null; MmsServiceBroker mmsService = null; HardwarePropertiesManagerService hardwarePropertiesService = null; PacProxyService pacProxyService = null; ... // 現在便可以開始啟動三方APP應用(如Launcher啟動桌面) mActivityManagerService.systemReady(() -> { ... }, t); // startOtherServices }

      經過上面這些步驟,我們調用調用createSystemContext()創建系統上下文的時候,也已經完成了mSystemContext和ActivityThread的創建。

      ATMS、AMS、WMS、PKMS等對象已經創建好了,并且完成了成員變量初始化。

      注意:這是系統進程開啟時的流程,在這之后,會開啟系統的 Launcher程序,完成系統界面的加載與顯示。

      在Android的框架設計中,服務器端指的就是所有App共用的系統服務,比如我們這里提到的ATMS、AMS、WMS、PKMS等等,這些基礎的系統服務是被所有的App公用的。

      3、Launcher是什么

      在Android系統中,系統進程開啟后,會開啟系統的 Launcher程序,完成系統界面的加載與顯示。其實,Launcher本身也是一個應用程序,其它的應用程序安裝后,就會Launcher的界面上出現一個相應的圖標,點擊這個圖標時,Launcher就會對應的應用程序啟動起來。

      當然也可以在 其他應用 啟動應用。但是本質上都是調用startActivity()。

      3.1 LauncherActivity.java

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

      /** * Displays a list of all activities which can be performed * for a given intent. Launches when clicked. * * @deprecated Applications can implement this UI themselves using * {@link androidx.recyclerview.widget.RecyclerView} and * {@link android.content.pm.PackageManager#queryIntentActivities(Intent, int)} */ @Deprecated public abstract class LauncherActivity extends ListActivity { ... @Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent intent = intentForPosition(position); startActivity(intent); } }

      小結

      附送整圖一張

      關于 startActivity() 有了解的可以直接看看。本篇內容太多我自己看著都鬧心。沒看過的關注走一波,詳細內容會在下一篇: ?? Android startActivity源碼分析 ??中講解。

      Android Linux 任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Oracle獲取執行計劃的方法(六脈神劍)
      下一篇:FPGA學習之VHDL語言總結
      相關文章
      亚洲精品福利网站| 亚洲精品V欧洲精品V日韩精品| 久久99亚洲综合精品首页| 亚洲精品美女久久7777777| 亚洲国产精品成人综合久久久 | 亚洲国产精品特色大片观看完整版| 亚洲中文字幕无码爆乳av中文| 国产亚洲精彩视频| 国产亚洲成在线播放va| 最新亚洲人成网站在线观看| 亚洲精品精华液一区二区| 亚洲丰满熟女一区二区哦| 亚洲乱码中文字幕在线| 亚洲国产香蕉人人爽成AV片久久| 国产成人亚洲综合无| 无码国产亚洲日韩国精品视频一区二区三区 | 亚洲精品视频在线免费| 亚洲精品日韩中文字幕久久久| 精品亚洲国产成AV人片传媒| 亚洲视频在线观看地址| 亚洲精品无码久久久久久久| 亚洲天堂一区在线| 亚洲精品亚洲人成在线播放| 亚洲色在线无码国产精品不卡| 亚洲精品乱码久久久久久蜜桃图片| 亚洲国产区男人本色| 国产精品亚洲一区二区无码 | 国产成人精品日本亚洲网址| 亚洲专区中文字幕| 在线亚洲高清揄拍自拍一品区| 亚洲精品无码久久久久APP | 老司机亚洲精品影院无码| 亚洲精品一区二区三区四区乱码| 亚洲制服丝袜一区二区三区| 亚洲成a人片在线观看中文动漫| 久久久久亚洲AV成人网人人网站| 亚洲精品无码不卡在线播放HE| 久久亚洲AV无码精品色午夜麻| 亚洲综合无码一区二区三区| 亚洲国产91在线| 亚洲av无码成人精品国产|