真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android中怎么創(chuàng)建進程

Android中怎么創(chuàng)建進程,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

榮昌網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),榮昌網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為榮昌上1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的榮昌做網(wǎng)站的公司定做!

Android系統(tǒng)以Linux內(nèi)核為基礎(chǔ),所以對于進程的管理自然離不開Linux本身提供的機制。例如:

  • 通過fork來創(chuàng)建進行

  • 通過信號量來管理進程

  • 通過proc文件系統(tǒng)來查詢和調(diào)整進程狀態(tài)等

對于Android來說,進程管理的主要內(nèi)容包括以下幾個部分內(nèi)容:

  • 進程的創(chuàng)建

  • 進程的優(yōu)先級管理

  • 進程的內(nèi)存管理

  • 進程的回收和死亡處理

本文會專門講解進程的創(chuàng)建,其余部分將在后面的文章中講解。

主要模塊

為了便于下文的講解,這里先介紹一下Android系統(tǒng)中牽涉到進程創(chuàng)建的幾個主要模塊。

同時為了便于讀者更詳細的了解這些模塊,這里也同時提供了這些模塊的代碼路徑。

這里提到的代碼路徑是指AOSP的源碼數(shù)中的路徑。

關(guān)于如何獲取AOSP源碼請參見這里:Downloading the Source。

本文以Android N版本的代碼為示例,所用到的Source Code Tags是:android-7.0.0_r1。

相關(guān)模塊:

  • app_process

代碼路徑:frameworks/base/cmds/app_process

說明:app_process是一個可執(zhí)行程序,該程序的主要作用是啟動zygote和system_server進程。

  • Zygote

代碼路徑:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

說明:zygote進程是所有應(yīng)用進程的父進程,這是系統(tǒng)中一個非常重要的進程,下文我們會詳細講解。

  • ActivityManager

代碼路徑:frameworks/base/services/core/java/com/android/server/am/

說明:am是ActivityManager的縮寫。

這個目錄下的代碼負責(zé)了Android全部四大組件(Activity,Service,ContentProvider,BroadcastReceiver)的管理,并且還掌控了所有應(yīng)用程序進程的創(chuàng)建和進程的優(yōu)先級管理。

因此,這個部分的內(nèi)容將是本系列文章講解的重點。

進程與線程

Android官方開發(fā)網(wǎng)站的這篇文章:Processes and Threads  非常好的介紹了Android系統(tǒng)中進程相關(guān)的一些基本概念和重要知識。

在閱讀下文之前,請務(wù)必將這篇文章瀏覽一遍。

關(guān)于進程

在Android系統(tǒng)中,進程可以大致分為系統(tǒng)進程和應(yīng)用進程兩大類。

系統(tǒng)進程是系統(tǒng)內(nèi)置的(例如:init,zygote,system_server進程),屬于操作系統(tǒng)必不可少的一部分。系統(tǒng)進程的作用在于:

  • 管理硬件設(shè)備

  • 提供訪問設(shè)備的基本能力

  • 管理應(yīng)用進程

應(yīng)用進程是指應(yīng)用程序運行的進程。這些應(yīng)用程序可能是系統(tǒng)出廠自帶的(例如Launcher,電話,短信等應(yīng)用),也可能是用戶自己安裝的(例如:微信,支付寶等)。

系統(tǒng)進程的數(shù)量通常是固定的(出廠或者系統(tǒng)升級之后就確定了),并且系統(tǒng)進程通常是一直存活,常駐內(nèi)存的。系統(tǒng)進程的異常退出將可能導(dǎo)致設(shè)備無法正常使用。

而應(yīng)用程序和應(yīng)用進程在每個人使用的設(shè)備上通常是各不一樣的。如何管理好這些不確定的應(yīng)用進程,就是操作系統(tǒng)本身要仔細考慮的內(nèi)容。也是衡量一個操作系統(tǒng)好壞的標準之一。

在本文中,我們會介紹init,zygote和system_server三個系統(tǒng)進程。

除此之外,本系列文章將會把主要精力集中在講解Android系統(tǒng)如何管理應(yīng)用進程上。

init進程

init進程是一切的開始,在Android系統(tǒng)中,所有進程的進程號都是不確定的,唯獨init進程的進程號一定是1。

因為這個進程一定是系統(tǒng)起來的***個進程。并且,init進程掌控了整個系統(tǒng)的啟動邏輯。

我們知道,Android可能運行在各種不同的平臺,不同的設(shè)備上。因此,啟動的邏輯是不盡相同的。

為了適應(yīng)各種平臺和設(shè)備的需求,init進程的初始化工作通過init.rc配置文件來管理。

你可以在AOSP源碼的system/core/rootdir/路徑找到這些配置文件。

配置文件的主入口文件是init.rc,這個文件會通過import引入其他幾個文件。

在本文中,我們統(tǒng)稱這些文件為init.rc。

init.rc通過Android Init Language來進行配置。

建議讀者大致閱讀一下其 語法說明 。

init.rc中配置了系統(tǒng)啟動的時候該做哪些事情,以及啟動哪些系統(tǒng)進程。

這其中有兩個特別重要的進程就是:zygote和system_server進程。

  • zygote的中文意思是“受精卵“。這是一個很有寓意的名稱:所有的應(yīng)用進程都是由zygote  fork出來的子進程,因此zygote進程是所有應(yīng)用進程的父進程。

  • system_server  這個進程正如其名稱一樣,這是一個系統(tǒng)服務(wù)器。Framework層的幾乎所有服務(wù)都位于這個進程中。這其中就包括管理四大組件的ActivityManagerService。

Zygote進程

init.rc文件會根據(jù)平臺不一樣,選擇下面幾個文件中的一個來啟動zygote進程:

  • init.zygote32.rc

  • init.zygote32_64.rc

  • init.zygote64.rc

  • init.zygote64_32.rc

這幾個文件的內(nèi)容是大致一致的,僅僅是為了不同平臺服務(wù)的。這里我們以init.zygote32.rc的文件為例,來看看其中的內(nèi)容:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server  class main  socket zygote stream 660 root system  onrestart write /sys/android_power/request_state wake  onrestart write /sys/power/state on  onrestart restart audioserver  onrestart restart cameraserver  onrestart restart media  onrestart restart netd  writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

在這段配置文件中(如果你不明白這段配置的含義,請閱讀一下文檔:Android Init  Language),啟動了一個名稱叫做zygote的服務(wù)進程。這個進程是通過/system/bin/app_process 這個可執(zhí)行程序創(chuàng)建的。

并且在啟動這個可執(zhí)行程序的時候,傳遞了`-Xzygote /system/bin --zygote --start-system-server

class main` 這些參數(shù)。

要知道這里到底做了什么,我們需要看一下app_process的源碼。

app_process的源碼在這個路徑:frameworks/base/cmds/app_process/app_main.cpp。

這個文件的main函數(shù)的有如下代碼:

int main(int argc, char* const argv[]) { ...     while (i < argc) {         const char* arg = argv[i++];         if (strcmp(arg, "--zygote") == 0) {             zygote = true;             niceName = ZYGOTE_NICE_NAME;         } else if (strcmp(arg, "--start-system-server") == 0) {             startSystemServer = true;         ...     }     ...    if (!className.isEmpty()) {         ...     } else {        ...             if (startSystemServer) {            args.add(String8("start-system-server"));        }     } ...     if (zygote) {         runtime.start("com.android.internal.os.ZygoteInit", args, zygote);     } else if (className) {         runtime.start("com.android.internal.os.RuntimeInit", args, zygote);     } else {         fprintf(stderr, "Error: no class name or --zygote supplied.\n");         app_usage();         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");         return 10;     } }

這里會判斷,

  • 如果執(zhí)行這個命令時帶了--zygote參數(shù),就會通過runtime.start啟動com.android.internal.os.ZygoteInit。

  • 如果參數(shù)中帶有--start-system-server參數(shù),就會將start-system-server添加到args中。

這段代碼是C++實現(xiàn)的。在執(zhí)行這段代碼的時候還沒有任何Java的環(huán)境。而runtime.start就是啟動Java虛擬機,并在虛擬機中啟動指定的類。于是接下來的邏輯就在ZygoteInit.java中了。

這個文件的main函數(shù)主要代碼如下:

public static void main(String argv[]) {    ...     try {        ...         boolean startSystemServer = false;        String socketName = "zygote";        String abiList = null;        for (int i = 1; i < argv.length; i++) {            if ("start-system-server".equals(argv[i])) {                startSystemServer = true;            } else if (argv[i].startsWith(ABI_LIST_ARG)) {                ...            }        }        ...        registerZygoteSocket(socketName);        ...        preload();        ...        Zygote.nativeUnmountStorageOnInit();         ZygoteHooks.stopZygoteNoThreadCreation();         if (startSystemServer) {            startSystemServer(abiList, socketName);        }         Log.i(TAG, "Accepting command socket connections");        runSelectLoop(abiList);         closeServerSocket();    } catch (MethodAndArgsCaller caller) {        caller.run();    } catch (RuntimeException ex) {        Log.e(TAG, "Zygote died with exception", ex);        closeServerSocket();        throw ex;    } }

在這段代碼中,我們主要關(guān)注如下幾行:

  1. 通過 registerZygoteSocket(socketName); 注冊Zygote Socket

  2. 通過 preload(); 預(yù)先加載所有應(yīng)用都需要的公共資源

  3. 通過 startSystemServer(abiList, socketName); 啟動system_server

  4. 通過 runSelectLoop(abiList); 在Looper上等待連接

這里需要說明的是:zygote進程啟動之后,會啟動一個socket套接字,并通過Looper一直在這個套接字上等待連接。

所有應(yīng)用進程都是通過發(fā)送數(shù)據(jù)到這個套接字上,然后由zygote進程創(chuàng)建的。

這里還有一點說明的是:

在Zygote進程中,會通過preload函數(shù)加載需要應(yīng)用程序都需要的公共資源。

預(yù)先加載這些公共資源有如下兩個好處:

  • 加快應(yīng)用的啟動速度 因為這些資源已經(jīng)在zygote進程啟動的時候加載好了

  • 通過共享的方式節(jié)省內(nèi)存  這是Linux本身提供的機制:父進程已經(jīng)加載的內(nèi)容可以在子進程中進行共享,而不用多份數(shù)據(jù)拷貝(除非子進程對這些數(shù)據(jù)進行了修改。)

preload的資源主要是Framework相關(guān)的一些基礎(chǔ)類和Resource資源,而這些資源正是所有應(yīng)用都需要的:

開發(fā)者通過Android SDK開發(fā)應(yīng)用所調(diào)用的API實現(xiàn)都在Framework中。

static void preload() {    Log.d(TAG, "begin preload");    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "BeginIcuCachePinning");    beginIcuCachePinning();    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");    preloadClasses();    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");    preloadResources();    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");    preloadOpenGL();    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);    preloadSharedLibraries();    preloadTextResources();     WebViewFactory.prepareWebViewInZygote();    endIcuCachePinning();    warmUpJcaProviders();    Log.d(TAG, "end preload"); }

system_server進程

上文已經(jīng)提到,zygote進程起來之后會根據(jù)需要啟動system_server進程。

system_server進程中包含了大量的系統(tǒng)服務(wù)。例如:

  • 負責(zé)網(wǎng)絡(luò)管理的NetworkManagementService

  • 負責(zé)窗口管理的WindowManagerService

  • 負責(zé)震動管理的VibratorService

  • 負責(zé)輸入管理的InputManagerService

等等。關(guān)于system_server,我們今后會其他的文章中專門講解,這里不做過多說明。

在本文中,我們只關(guān)注system_server中的ActivityManagerService這個系統(tǒng)服務(wù)。

ActivityManagerService

上文中提到:zygote進程在啟動之后會啟動一個socket,然后一直在這個socket等待連接。

而會連接它的就是ActivityManagerService。因為ActivityManagerService掌控了所有應(yīng)用進程的創(chuàng)建。

所有應(yīng)用程序的進程都是由ActivityManagerService通過socket發(fā)送請求給Zygote進程,然后由zygote  fork創(chuàng)建的。

ActivityManagerService通過Process.start方法來請求zygote創(chuàng)建進程:

public static final ProcessStartResult start(final String processClass,                              final String niceName,                              int uid, int gid, int[] gids,                              int debugFlags, int mountExternal,                              int targetSdkVersion,                              String seInfo,                              String abi,                              String instructionSet,                              String appDataDir,                              String[] zygoteArgs) {    try {        return startViaZygote(processClass, niceName, uid, gid, gids,                debugFlags, mountExternal, targetSdkVersion, seInfo,                abi, instructionSet, appDataDir, zygoteArgs);    } catch (ZygoteStartFailedEx ex) {        Log.e(LOG_TAG,                "Starting VM process through Zygote failed");        throw new RuntimeException(                "Starting VM process through Zygote failed", ex);    } }

這個函數(shù)會將啟動進程所需要的參數(shù)組裝好,并通過socket發(fā)送給zygote進程。然后zygote進程根據(jù)發(fā)送過來的參數(shù)將進程fork出來。

在ActivityManagerService中,調(diào)用Process.start的地方是下面這個方法:

private final void startProcessLocked(ProcessRecord app, String hostingType,        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {         ...   Process.ProcessStartResult startResult = Process.start(entryPoint,           app.processName, uid, uid, gids, debugFlags, mountExternal,           app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,           app.info.dataDir, entryPointArgs); ... }

下文中我們會看到,所有四大組件進程的創(chuàng)建,都是調(diào)用這里的startProcessLocked這個方法而創(chuàng)建的。

對于每一個應(yīng)用進程,在ActivityManagerService中,都有一個ProcessRecord與之對應(yīng)。這個對象記錄了應(yīng)用進程的所有詳細狀態(tài)。

PS:對于ProcessRecord的內(nèi)部結(jié)構(gòu),在下一篇文章中,我們會講解。

為了查找方便,對于每個ProcessRecord會存在下面兩個集合中。

  • 按名稱和uid組織的集合:

/** * All of the applications we currently have running organized by name. * The keys are strings of the application package name (as * returned by the package manager), and the keys are ApplicationRecord * objects. */ final ProcessMap mProcessNames = new ProcessMap();
  • 按pid組織的集合:

/** * All of the processes we currently have running organized by pid. * The keys are the pid running the application. * * 

NOTE: This object is protected by its own lock, NOT the global * activity manager lock! */ final SparseArray mPidsSelfLocked = new SparseArray();

下面這幅圖小節(jié)了上文的這些內(nèi)容:

關(guān)于應(yīng)用組件

Processes and Threads 提到:

“當某個應(yīng)用組件啟動且該應(yīng)用沒有運行其他任何組件時,Android 系統(tǒng)會使用單個執(zhí)行線程為應(yīng)用啟動新的 Linux 進程?!?/p>

因此,四大組件中的任何一個先起來都會導(dǎo)致應(yīng)用進程的創(chuàng)建。下文我們就詳細看一下,它們啟動時,各自是如何導(dǎo)致應(yīng)用進程的創(chuàng)建的。

PS:四大組件的管理本身又是一個比較大的話題,限于篇幅關(guān)系,這里不會非常深入的講解,這里主要是講解四大組件與進程創(chuàng)建的關(guān)系。

在應(yīng)用程序中,開發(fā)者通過:

  • startActivity(Intent intent) 來啟動Activity

  • startService(Intent service) 來啟動Service

  • sendBroadcast(Intent intent) 來發(fā)送廣播

  • ContentResolver 中的接口來使用ContentProvider

這其中,startActivity,startService和sendBroadcast還有一些重載方法。

其實這里提到的所有這些方法,最終都是通過Binder調(diào)用到ActivityManagerService中,由其進行處理的。

這里特別說明一下:應(yīng)用進程和ActivityManagerService所在進程(即system_server進程)是相互獨立的,兩個進程之間的方法通常是不能直接互相調(diào)用的。

而Android系統(tǒng)中,專門提供了Binder框架來提供進程間通訊和方法調(diào)用的能力。

調(diào)用關(guān)系如下圖所示:

Activity與進程創(chuàng)建

在ActivityManagerService中,對每一個運行中的Activity都有一個ActivityRecord對象與之對應(yīng),這個對象記錄Activity的詳細狀態(tài)。

ActivityManagerService中的startActivity方法接受Context.startActivity的請求,該方法代碼如下:

@Override public final int startActivity(IApplicationThread caller, String callingPackage,        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,            resultWho, requestCode, startFlags, profilerInfo, bOptions,            UserHandle.getCallingUserId()); }

Activity的啟動是一個非常復(fù)雜的過程。這里我們簡單介紹一下背景知識:

  • ActivityManagerService中通過Stack和Task來管理Activity

  • 每一個Activity都屬于一個Task,一個Task可能包含多個Activity。一個Stack包含多個Task

  • ActivityStackSupervisor類負責(zé)管理所有的Stack

  • Activity的啟動過程會牽涉到:

    • Intent的解析

    • Stack,Task的查詢或創(chuàng)建

    • Activity進程的創(chuàng)建

    • Activity窗口的創(chuàng)建

    • Activity的生命周期調(diào)度

Activity的管理結(jié)構(gòu)如下圖所示:

在Activity啟動的***,會將前一個Activity pause,將新啟動的Activity resume以便被用戶看到。

在這個時候,如果發(fā)現(xiàn)新啟動的Activity進程還沒有啟動,則會通過startSpecificActivityLocked將其啟動。整個調(diào)用流程如下:

  • ActivityManagerService.activityPaused =>

  • ActivityStack.activityPausedLocked =>

  • ActivityStack.completePauseLocked =>

  • ActivityStackSupervisor.ensureActivitiesVisibleLocked =>

  • ActivityStack.makeVisibleAndRestartIfNeeded =>

  • ActivityStackSupervisor.startSpecificActivityLocked =>

  • ActivityManagerService.startProcessLocked

  • ActivityStackSupervisor.startSpecificActivityLocked 關(guān)鍵代碼如下:

void startSpecificActivityLocked(ActivityRecord r,        boolean andResume, boolean checkConfig) {    // Is this activity's application already running?    ProcessRecord app = mService.getProcessRecordLocked(r.processName,            r.info.applicationInfo.uid, true);     r.task.stack.setLaunchTime(r);     if (app != null && app.thread != null) {        ...    }     mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,            "activity", r.intent.getComponent(), false, false, true); }

這里的ProcessRecord app 描述了Activity所在進程。

Service與進程創(chuàng)建

Service的啟動相對于Activity來說要簡單一些。

在ActivityManagerService中,對每一個運行中的Service都有一個ServiceRecord對象與之對應(yīng),這個對象記錄Service的詳細狀態(tài)。

ActivityManagerService中的startService方法處理Context.startServiceAPI的請求,相關(guān)代碼:

@Override public ComponentName startService(IApplicationThread caller, Intent service,        String resolvedType, String callingPackage, int userId)        throws TransactionTooLargeException {    ...    synchronized(this) {        final int callingPid = Binder.getCallingPid();        final int callingUid = Binder.getCallingUid();        final long origId = Binder.clearCallingIdentity();        ComponentName res = mServices.startServiceLocked(caller, service,                resolvedType, callingPid, callingUid, callingPackage, userId);        Binder.restoreCallingIdentity(origId);        return res;    } }

這段代碼中的mServices對象是ActiveServices類型的,這個類專門負責(zé)管理活動的Service。

啟動Service的調(diào)用流程如下:

  • ActivityManagerService.startService =>

  • ActiveServices.startServiceLocked =>

  • ActiveServices.startServiceInnerLocked =>

  • ActiveServices.bringUpServiceLocked =>

  • ActivityManagerService.startProcessLocked

ActiveServices.bringUpServiceLocked會判斷如果Service所在進程還沒有啟動,

則通過ActivityManagerService.startProcessLocked將其啟動。相關(guān)代碼如下:

// Not running -- get it started, and enqueue this service record // to be executed when the app comes up. if (app == null && !permissionsReviewRequired) {   if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,           "service", r.name, false, isolated, false)) == null) {       String msg = "Unable to launch app "               + r.appInfo.packageName + "/"               + r.appInfo.uid + " for service "               + r.intent.getIntent() + ": process is bad";       Slog.w(TAG, msg);       bringDownServiceLocked(r);       return msg;   }   if (isolated) {       r.isolatedProc = app;   } }

這里的mAm 就是ActivityManagerService。

Provider與進程創(chuàng)建

在ActivityManagerService中,對每一個運行中的ContentProvider都有一個ContentProviderRecord對象與之對應(yīng),這個對象記錄ContentProvider的詳細狀態(tài)。

開發(fā)者通過ContentResolver中的insert, delete, update,  query這些API來使用ContentProvider。在ContentResolver的實現(xiàn)中,無論使用這里的哪個接口,ContentResolver都會先通過acquireProvider  這個方法來獲取到一個類型為IContentProvider的遠程接口。這個遠程接口對接了ContentProvider的實現(xiàn)提供方。

同一個ContentProvider可能同時被多個模塊使用,而調(diào)用ContentResolver接口的進程只是ContentProvider的一個客戶端而已,真正的ContentProvider提供方是運行自身的進程中的,兩個進程的通訊需要通過Binder的遠程接口形式來調(diào)用。如下圖所示:

ContentResolver.acquireProvider  最終會調(diào)用到ActivityManagerService.getContentProvider中,該方法代碼如下:

@Override public final ContentProviderHolder getContentProvider(        IApplicationThread caller, String name, int userId, boolean stable) {    enforceNotIsolatedCaller("getContentProvider");    if (caller == null) {        String msg = "null IApplicationThread when getting content provider "                + name;        Slog.w(TAG, msg);        throw new SecurityException(msg);    }    // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal    // with cross-user grant.    return getContentProviderImpl(caller, name, null, stable, userId); }

而在getContentProviderImpl這個方法中,會判斷對應(yīng)的ContentProvider進程有沒有啟動,

如果沒有,則通過startProcessLocked方法將其啟動。

Receiver與進程創(chuàng)建

開發(fā)者通過Context.sendBroadcast接口來發(fā)送廣播。ActivityManagerService.broadcastIntent  方法了對應(yīng)廣播發(fā)送的處理。

廣播是一種一對多的消息形式,廣播接受者的數(shù)量是不確定的。因此發(fā)送廣播本身可能是一個很耗時的過程(因為要逐個通知)。

在ActivityManagerService內(nèi)部,是通過隊列的形式來管理廣播的:

  • BroadcastQueue 描述了一個廣播隊列

  • BroadcastRecord 描述了一個廣播事件

在ActivityManagerService中,如果收到了一個發(fā)送廣播的請求,會先創(chuàng)建一個BroadcastRecord接著將其放入BroadcastQueue中。

然后通知隊列自己去處理這個廣播。然后ActivityManagerService自己就可以繼續(xù)處理其他請求了。

廣播隊列本身是在另外一個線程處理廣播的發(fā)送的,這樣保證的ActivityManagerService主線程的負載不會太重。

在BroadcastQueue.processNextBroadcast(boolean fromMsg)  方法中真正實現(xiàn)了通知廣播事件到接受者的邏輯。在這個方法,如果發(fā)現(xiàn)接受者(即BrodcastReceiver)還沒有啟動,便會通過ActivityManagerService.startProcessLocked  方法將其啟動。相關(guān)如下所示:

final void processNextBroadcast(boolean fromMsg) {     ...        // Hard case: need to instantiate the receiver, possibly        // starting its application process to host it.         ResolveInfo info =            (ResolveInfo)nextReceiver;        ComponentName component = new ComponentName(                info.activityInfo.applicationInfo.packageName,                info.activityInfo.name);     ...        // Not running -- get it started, to be executed when the app comes up.        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,                "Need to start app ["                + mQueueName + "] " + targetProcess + " for broadcast " + r);        if ((r.curApp=mService.startProcessLocked(targetProcess,                info.activityInfo.applicationInfo, true,                r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,                "broadcast", r.curComponent,                (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))                        == null) {            // Ah, this recipient is unavailable.  Finish it if necessary,            // and mark the broadcast record as ready for the next.            Slog.w(TAG, "Unable to launch app "                    + info.activityInfo.applicationInfo.packageName + "/"                    + info.activityInfo.applicationInfo.uid + " for broadcast "                    + r.intent + ": process is bad");            logBroadcastReceiverDiscardLocked(r);            finishReceiverLocked(r, r.resultCode, r.resultData,                    r.resultExtras, r.resultAbort, false);            scheduleBroadcastsLocked();            r.state = BroadcastRecord.IDLE;            return;        }         mPendingBroadcast = r;        mPendingBroadcastRecvIndex = recIdx;    } }

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。


網(wǎng)站欄目:Android中怎么創(chuàng)建進程
本文地址:http://weahome.cn/article/jpgcdd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部