国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android APP啟動流程解析

這篇具有很好參考價值的文章主要介紹了Android APP啟動流程解析。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

手機啟動

Android手機在開機Linux內(nèi)核啟動的時候,會加載system/core/init/init.rc文件,啟動init進(jìn)程,這個是Android特有的初始化程序,主要負(fù)責(zé)

  • 各種復(fù)雜工作
  • 負(fù)責(zé)開關(guān)機畫面
  • 文件系統(tǒng)的創(chuàng)建和掛載
  • 啟動Zygote(孵化器)進(jìn)程
  • 啟動ServiceManager,它是Binder服務(wù)管理器,管理所有Android系統(tǒng)服務(wù)

fork Zygote

在啟動init進(jìn)程后會fork Zygote進(jìn)程,它是一個孵化器進(jìn)程,它的main函數(shù)會創(chuàng)建好環(huán)境并且等待孵化,接到指令后就會開始fork子進(jìn)程
創(chuàng)建一個server端的socket, name為zynote,用于和客戶端進(jìn)程通信
預(yù)加載類和資源,提高應(yīng)用啟動速度
啟動SystemServer進(jìn)程
監(jiān)聽socket,當(dāng)有一個應(yīng)用程序啟動時,就會向它發(fā)出請求,然后zygote進(jìn)程fock自己來創(chuàng)建的一個新的子進(jìn)程。
所以說Android內(nèi)所有的應(yīng)用其實都是Zygote的子進(jìn)程

SystemServer

SystemServer是由zygote進(jìn)程fork出來的第一個進(jìn)程,SystemServer和Zygote是Android Framework最重要的2個進(jìn)程。 系統(tǒng)里面重要的服務(wù)都是在這個進(jìn)程里面開啟的,比如ActivityManagerService(AMS)、PackageManagerService(PMS)、WindowManagerService(WMS)。
應(yīng)用啟動流程基本是圍繞著ActivityManagerService和ActivityThread展開。
并且負(fù)責(zé)啟動并且管理整個framework。
ActivityManagerService
ActivityManagerService,簡稱AMS,服務(wù)端對象,負(fù)責(zé)系統(tǒng)中所有Activity的生命周期。
并且他在SystemServer進(jìn)程開啟的時候,就會直接跟著一起初始化

應(yīng)用啟動

涉及進(jìn)程

Android開發(fā)中,我們可以通過Package包名和Activity類名,來打開一個APP。實際上,項目里的業(yè)務(wù)代碼startActivity()方法并不是直接創(chuàng)建進(jìn)程、拉起APP的。而是通過一系列的調(diào)用,把請求傳遞給SystemServer的AMS。AMS收到來自客戶端的請求后,再通知zygote進(jìn)程來fork一個新進(jìn)程,來開啟我們的目標(biāo)APP。APP中所有Activity的生命周期過程,都由AMS(SystemServer進(jìn)程)統(tǒng)一調(diào)度,并在APP自身進(jìn)程中具體完成。
所以打開應(yīng)用總共涉及了三個進(jìn)程:Zygote進(jìn)程、AMS進(jìn)程、APP進(jìn)程
App進(jìn)程與AMS通過Binder機制進(jìn)行跨進(jìn)程通信
AMS(SystemServer進(jìn)程)與zygote通過Socket進(jìn)行跨進(jìn)程通信。
在Android系統(tǒng)中,任何一個Activity的啟動都是由AMS和App進(jìn)程(主要是ActivityThread)相互配合來完成的。AMS服務(wù)統(tǒng)一調(diào)度系統(tǒng)中所有進(jìn)程的Activity啟動,而每個Activity的啟動過程則由其所屬的進(jìn)程具體來完成。

啟動步驟
  1. activity中的startActivity方法最終都會通過拿到ATSM的代理IActivityTaskManager調(diào)用的startActivity;
  2. 之后進(jìn)入system server進(jìn)程中的ATMS startActivity,ATMS 經(jīng)過收集Intent信息,然后使用ActivityStackSupervisor.startSpecificActivityLocked,如果進(jìn)程已經(jīng)存在,則直接使用realStartActivityLocked,通過App的binder客戶端的代理ApplicationThread調(diào)用回到bindApplication,走入Activity的啟動流程;如果進(jìn)程不存在則通過socket鏈接Zygote,請求fork新的進(jìn)程;
  3. App進(jìn)程創(chuàng)建完成后,進(jìn)程啟動會調(diào)用ActivityThread.main方法,初始化主線程Handler,接著走入attach方法,然后通過AMS的代理調(diào)用AMS的attachApplication方法,并將App進(jìn)程的通信代理ApplicationThread傳入AMS;
  4. AMS獲取到ATMS調(diào)用ApplicationThread的bindApplication回到App進(jìn)程的ActivityThread.ApplicationThread.bindApplication方法中,然后使用Handler切換到主線程執(zhí)行handleBindApplication,這里初始化了App的進(jìn)程名字、時間,用戶的硬件配置,包括App的文件系統(tǒng),創(chuàng)建了App的Context實例,Instrumentation實例,調(diào)用App的onCreate回調(diào)方法,同時告訴AMS APP初始化工作完畢;
  5. AMS接著會調(diào)用ATMS的attachApplication,最后調(diào)用ClientLifecycleManager的scheduleTransaction方法,通過App的Binder代理ApplicationThread回到ActivityThread;
  6. 進(jìn)入ActivityThread.ApplicationThread.scheduleTransaction方法之后就進(jìn)入了Activity的onStart、onResume回調(diào)

流程

ActivityThread

一個應(yīng)用,在被點擊后首先要fork出一個Zygote進(jìn)程,接下來執(zhí)行ActivityThread.main
frameworks/base/core/java/android/app/ActivityThread.java

public static void main(String[] args) { 
    ActivityThread thread = new ActivityThread(); 
    thread.attach(false, startSeq); 
    if (sMainThreadHandler == null) { 
        sMainThreadHandler = thread.getHandler(); 
    } 
    if (false) { 
        Looper.myLooper().setMessageLogging(new 
                LogPrinter(Log.DEBUG, "ActivityThread")); 
    } 
    // End of event ActivityThreadMain. 
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
    Looper.loop(); 
    throw new RuntimeException("Main thread loop unexpectedly exited"); 
}

然后調(diào)用ActivityThread的attach方法,然后將activity和AMS通信的Binder代理IApplicationThread實例傳入AMS
frameworks/base/core/java/android/app/ActivityThread.java

@UnsupportedAppUsage 
private void attach(boolean system, long startSeq) { 
    sCurrentActivityThread = this; 
    mSystemThread = system; 
    if (!system) { 
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 
                                                UserHandle.myUserId()); 
        RuntimeInit.setApplicationObject(mAppThread.asBinder()); 
        final IActivityManager mgr = ActivityManager.getService(); 
        try { 
            mgr.attachApplication(mAppThread, startSeq); 
        } catch (RemoteException ex) { 
            throw ex.rethrowFromSystemServer(); 
        } 
        // Watch for getting close to heap limit. 
        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(); 
                if (dalvikUsed > ((3*dalvikMax)/4)) { 
                    if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) 
                            + " total=" + (runtime.totalMemory()/1024) 
                            + " used=" + (dalvikUsed/1024)); 
                    mSomeActivitiesChanged = false; 
                    try { 
                        ActivityTaskManager.getService().releaseSomeActivities(mAppThread); 
                    } catch (RemoteException e) { 
                        throw e.rethrowFromSystemServer(); 
                    } 
                } 
            } 
        }); 
    }  
}
AMS

接著進(jìn)入AMS進(jìn)程,ActivityManagerService.attachApplicationLocked
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

private final boolean attachApplicationLocked(IApplicationThread thread, 
        int pid, int callingUid, long startSeq) { 
        if (app.isolatedEntryPoint != null) { 
            // This is an isolated process which should just call an entry point instead of 
            // being bound to an application. 
            thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); 
        } else if (instr2 != null) { 
            thread.bindApplication(processName, appInfo, providers, 
                    instr2.mClass, 
                    profilerInfo, instr2.mArguments, 
                    instr2.mWatcher, 
                    instr2.mUiAutomationConnection, testMode, 
                    mBinderTransactionTrackingEnabled, enableTrackAllocation, 
                    isRestrictedBackupMode || !normalMode, app.isPersistent(), 
                    new Configuration(app.getWindowProcessController().getConfiguration()), 
                    app.compat, getCommonServicesLocked(app.isolated), 
                    mCoreSettingsObserver.getCoreSettingsLocked(), 
                    buildSerial, autofillOptions, contentCaptureOptions); 
        } else { 
            thread.bindApplication(processName, appInfo, providers, null, profilerInfo, 
                    null, null, null, testMode, 
                    mBinderTransactionTrackingEnabled, enableTrackAllocation, 
                    isRestrictedBackupMode || !normalMode, app.isPersistent(), 
                    new Configuration(app.getWindowProcessController().getConfiguration()), 
                    app.compat, getCommonServicesLocked(app.isolated), 
                    mCoreSettingsObserver.getCoreSettingsLocked(), 
                    buildSerial, autofillOptions, contentCaptureOptions); 
        } 
    } catch (Exception e) { 
    } 
    // See if the top visible activity is waiting to run in this process... 
    if (normalMode) { 
        try { 
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); 
        } catch (Exception e) { 
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 
            badApp = true; 
        } 
    } 
    // Find any services that should be running in this process... 
    if (!badApp) { 
        try { 
            didSomething |= mServices.attachApplicationLocked(app, processName); 
            checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); 
        } catch (Exception e) { 
            Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 
            badApp = true; 
        } 
    } 
    return true; 
}

thread.bindApplication:該方法主要講App進(jìn)程的配置信息通過IApplicationThread Binder通信回傳到ActivityThread中;
mAtmInternal.attachApplication:mAtmInternal實際就是ActivityTaskManager的實例,通過LocalServices加載;
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);

那么這里相當(dāng)于走到了ActivityTaskManagerServer的attachApplication中;
frameworks/base/core/java/android/app/ActivityThread.java

@Override 
public final void bindApplication(String processName, ApplicationInfo appInfo, 
        ProviderInfoList providerList, ComponentName instrumentationName, 
        ProfilerInfo profilerInfo, Bundle instrumentationArgs, 
        IInstrumentationWatcher instrumentationWatcher, 
        IUiAutomationConnection instrumentationUiConnection, int debugMode, 
        boolean enableBinderTracking, boolean trackAllocation, 
        boolean isRestrictedBackupMode, boolean persistent, Configuration config, 
        CompatibilityInfo compatInfo, Map services, Bundle coreSettings, 
        String buildSerial, AutofillOptions autofillOptions, 
        ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) { 
    setCoreSettings(coreSettings); 
    AppBindData data = new AppBindData(); 
    data.processName = processName; 
    ..... 
    sendMessage(H.BIND_APPLICATION, data); 
}

這里的bindApplication主要初始化了AppBindData,然后發(fā)送BIND_APPLICATION給APP的主線程BIND_APPLICATION,最后執(zhí)行了handleBindApplication
frameworks/base/core/java/android/app/ActivityThread.java

case BIND_APPLICATION: 
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); 
    AppBindData data = (AppBindData)msg.obj; 
    handleBindApplication(data); 
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 
    break;

Application的onCreate方法
frameworks/base/core/java/android/app/ActivityThread.java

private void handleBindApplication(AppBindData data) { 
          mBoundApplication = data; 
        mConfiguration = new Configuration(data.config); 
        mCompatConfiguration = new Configuration(data.config); 
         if (data.initProfilerInfo != null) { 
            mProfiler.profileFile = data.initProfilerInfo.profileFile; 
            mProfiler.profileFd = data.initProfilerInfo.profileFd; 
            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval; 
            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; 
            mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput; 
            if (data.initProfilerInfo.attachAgentDuringBind) { 
                agent = data.initProfilerInfo.agent; 
            } 
        } 
mInstrumentationPackageName = ii.packageName; 
            mInstrumentationAppDir = ii.sourceDir; 
            mInstrumentationSplitAppDirs = ii.splitSourceDirs; 
            mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); 
            mInstrumentedAppDir = data.info.getAppDir(); 
            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); 
            mInstrumentedLibDir = data.info.getLibDir(); 
             mInstrumentation.callApplicationOnCreate(app); 
}

這個方法主要在App進(jìn)程中對App的一些硬件資源配置申請的屬性、App的文件夾等完成App基本信息的初始化
并且
mAtmInternal.attachApplication最終會調(diào)用mRootActivityContainer.attachApplication(wpc)
RootActivityContainer.attachApplication
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

boolean attachApplication(WindowProcessController app) throws RemoteException { 
    final String processName = app.mName; 
    boolean didSomething = false; 
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 
        final ActivityDisplay display = mActivityDisplays.get(displayNdx); 
        final ActivityStack stack = display.getFocusedStack(); 
        if (stack != null) { 
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); 
            //獲取前臺棧頂?shù)谝粋€非finishing的Activity 
            final ActivityRecord top = stack.topRunningActivityLocked(); 
            final int size = mTmpActivityList.size(); 
            for (int i = 0; i < size; i++) { 
                final ActivityRecord activity = mTmpActivityList.get(i); 
                if (activity.app == null && app.mUid == activity.info.applicationInfo.uid 
                        && processName.equals(activity.processName)) { 
                    try { 
                    //真正啟動Activity 
                        if (mStackSupervisor.realStartActivityLocked(activity, app, 
                                top == activity /* andResume */, true /* checkConfig */)) { 
                            didSomething = true; 
                        } 
                    } catch (RemoteException e) { 
                        Slog.w(TAG, "Exception in new application when starting activity " 
                                + top.intent.getComponent().flattenToShortString(), e); 
                        throw e; 
                    } 
                } 
            } 
        } 
    } 
    if (!didSomething) { 
        ensureActivitiesVisible(null, 0, false /* preserve_windows */); 
    } 
    return didSomething; 
}

接著調(diào)用ActivityStackSupervisor開始創(chuàng)建Activity

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, 
            boolean andResume, boolean checkConfig) throws RemoteException { 
    try { 
        r.startFreezingScreenLocked(app, 0); 
        //啟動tick,收集應(yīng)用啟動慢的信息 
        // schedule launch ticks to collect information about slow apps. 
        r.startLaunchTickingLocked(); 
        r.setProcess(app); 
        try { 
            //創(chuàng)建Activity啟動事務(wù) 
            // Create activity launch transaction. 
            final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, 
                    r.appToken); 
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), 
                    System.identityHashCode(r), r.info, 
                    // TODO: Have this take the merged configuration instead of separate global 
                    // and override configs. 
                    mergedConfiguration.getGlobalConfiguration(), 
                    mergedConfiguration.getOverrideConfiguration(), r.compat, 
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, 
                    r.persistentState, results, newIntents, mService.isNextTransitionForward(), 
                    profilerInfo)); 
            //設(shè)置目標(biāo)事務(wù)的狀態(tài)為onResume 
            // Set desired final state. 
            final ActivityLifecycleItem lifecycleItem; 
            if (andResume) { 
                lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); 
            } else { 
                lifecycleItem = PauseActivityItem.obtain(); 
            } 
            clientTransaction.setLifecycleStateRequest(lifecycleItem); 
            //通過transaciton方式開始activity生命周期,onCreate,onStart,onResume 
            // Schedule transaction. 
            mService.getLifecycleManager().scheduleTransaction(clientTransaction); 
        } catch (RemoteException e) { 
        } 
    } finally { 
        endDeferResume(); 
    } 
    return true; 
}

在這個方法中間ClientLifecycleManager.scheduleTransaction最終會調(diào)用ClientTransaction的schedule方法,然后這個方法實際上會回調(diào)回ActivityThread
運用了IApplicationThread ,也就是AMS和ActivityThread通信的橋梁
APP.onCreate
所以我們調(diào)用

@Override 
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { 
    ActivityThread.this.scheduleTransaction(transaction); 
}

void scheduleTransaction(ClientTransaction transaction) { 
    transaction.preExecute(this); 
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); 
}
......
(最后再調(diào)用了幾個方法,根據(jù)代碼走就可以了沒啥特殊的這里就不放了)

最后調(diào)用了activity.attach方法。
在這期間,ActivityThread做了這樣幾件事
通過反射創(chuàng)建Activity實例,這是通過Instrumentation.newActivity方法實現(xiàn)的;
調(diào)用Activity的onCreate回調(diào);
通過Activity.attach方法,實例化Window對象;文章來源地址http://www.zghlxwxcb.cn/news/detail-841782.html

到了這里,關(guān)于Android APP啟動流程解析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Android】AMS(三)APP啟動流程

    【Android】AMS(三)APP啟動流程

    在 Android 系統(tǒng)中,啟動一個應(yīng)用程序可以分為三種啟動方式: 熱啟動 、 冷啟動 和 溫啟動 。它們分別表示了不同的啟動方式和啟動過程。 熱啟動 熱啟動是指在已經(jīng)打開并處于后臺運行的應(yīng)用程序中,再次通過圖標(biāo)進(jìn)入應(yīng)用程序的啟動方式。這時應(yīng)用程序的進(jìn)程已經(jīng)存在,

    2024年02月08日
    瀏覽(18)
  • Android系統(tǒng)啟動流程 源碼解析

    本文鏈接:https://blog.csdn.net/feather_wch/article/details/132518105 有道云腦圖:https://note.youdao.com/s/GZ9d8vzO 1、整體流程 Boot Room BootLoader idle kthread init init ServiceManager zygote zygote SystemServer app 1、kernel/common/init/main.c 2、andorid.mk-android.bp編譯 3、init是用戶空間鼻祖 屬于C、C++ Framework 1.1 啟動源

    2024年02月11日
    瀏覽(30)
  • Android S從桌面點擊圖標(biāo)啟動APP流程 (六)

    系列文章 Android S從桌面點擊圖標(biāo)啟動APP流程 (一) Android S從桌面點擊圖標(biāo)啟動APP流程 (二) Android S從桌面點擊圖標(biāo)啟動APP流程 (三) Android S從桌面點擊圖標(biāo)啟動APP流程 (四) Android S從桌面點擊圖標(biāo)啟動APP流程 (五) Android 12的源碼鏈接: android 12 aosp http://aospxref.com/android-12.0.0_r3/ 上文

    2024年02月06日
    瀏覽(28)
  • Android應(yīng)用啟動流程:從啟動到可交互的過程解析

    Android應(yīng)用啟動流程:從啟動到可交互的過程解析

    關(guān)于作者:CSDN內(nèi)容合伙人、技術(shù)專家, 從零開始做日活千萬級APP。 專注于分享各領(lǐng)域原創(chuàng)系列文章 ,擅長java后端、移動開發(fā)、人工智能等,希望大家多多支持。 我們繼續(xù)總結(jié)學(xué)習(xí) Android 基礎(chǔ)知識 ,溫故知新。 還是在多年前做系統(tǒng)應(yīng)用開發(fā)的時候,通過編譯源碼學(xué)習(xí)了一

    2024年02月11日
    瀏覽(17)
  • Android Framework學(xué)習(xí)之Activity啟動原理

    Android Framework學(xué)習(xí)之Activity啟動原理

    Android 13.0 Activity啟動原理邏輯流程圖如下:

    2024年02月05日
    瀏覽(24)
  • 【Android12】Android Framework系列---Adb和PMS安裝apk源碼流程

    【Android12】Android Framework系列---Adb和PMS安裝apk源碼流程

    通過adb install命令可以將apk安裝到Android系統(tǒng)(注意:特定類型的apk,比如persist類型是無法通過adb安裝的) 下述命令中adb解析install命令,并調(diào)用Android PackageManagerService進(jìn)行apk安裝。 基于Android12,分析從adb install到 PakcageManagerService安裝apk的流程。 adb install命令的源碼實現(xiàn) Andro

    2024年01月22日
    瀏覽(44)
  • Android Framework解析——WMS原理

    Android Framework解析——WMS原理

    作者:bobby_developer window:它是一個抽象類,具體實現(xiàn)類為 PhoneWindow ,它對 View 進(jìn)行管理。Window是View的容器,View是Window的具體表現(xiàn)內(nèi)容; windowManager:是一個接口類,繼承自接口 ViewManager ,從它的名稱就知道它是用來管理 Window 的,它的實現(xiàn)類為 WindowManagerImpl; WMS:是窗口的管理

    2024年02月13日
    瀏覽(21)
  • Android9.0 系統(tǒng)Framework發(fā)送通知流程分析

    Android9.0 系統(tǒng)Framework發(fā)送通知流程分析

    ? 在android 9.0的系統(tǒng)rom定制化開發(fā)中,在systemui中一個重要的內(nèi)容就是系統(tǒng)通知的展示,在狀態(tài)欄展示系統(tǒng)發(fā)送通知的圖標(biāo),而在 系統(tǒng)下拉通知欄中展示接收到的系統(tǒng)發(fā)送過來的通知,所以說對系統(tǒng)framework中發(fā)送通知的流程分析很重要,接下來就來分析下系統(tǒng) 通知從framework到

    2024年02月02日
    瀏覽(23)
  • android framework之AMS的啟動管理與職責(zé)

    AMS是什么? AMS管理著activity,Service, Provide, BroadcastReceiver android10后:出現(xiàn)ATMS,ActivityTaskManagerService:ATMS是從AMS中抽出來,單獨管理著原來AMS中的Activity組件 。 現(xiàn)在我們對AMS的分析,也就包含對ATMS的分析了。 AMS如何被別人管理?---被SystemServer的SystemServiceManager所管理 AMS如何被人

    2024年02月10日
    瀏覽(24)
  • Android Framework 常見解決方案(24)屏蔽FallbackHome,去除 Android正在啟動,直接進(jìn)入Launcher

    開機以后,設(shè)備會有一個“android正在啟動”這樣的彈框,這個界面是一個叫FallbackHome的Activity來展示的。FallbackHome機制是Android系統(tǒng)啟動過程中的一種降級處理機制。當(dāng)系統(tǒng)啟動時,如果默認(rèn)的Launcher應(yīng)用無法正常加載或出現(xiàn)錯誤,系統(tǒng)會自動啟用FallbackHome來替代默認(rèn)Launcher。

    2024年01月24日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包