日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

service启动activity_「 Android 10 四大组件 」系列—Service 的 quot; 启动流程 quot;

發布時間:2024/7/5 Android 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 service启动activity_「 Android 10 四大组件 」系列—Service 的 quot; 启动流程 quot; 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:DeepCoder

核心源碼

關鍵類路徑

Service 的啟動過程相對 Activity 的啟動過程來說簡單了很多,我們都知道怎么去創建和啟動一個 Service, 那么你有沒有從源碼角度研究過 Service 啟動后在系統層是如何運作的 ?

第一次看我文章的小伙伴可以關注一下我,順便關注一下我的專欄:Android高級開發架構技術專欄,每天更新各種技術干貨,分享更多最熱程序員圈內事。Android高級開發架構技術專欄?zhuanlan.zhihu.com

Activity.startService()

首先我們知道:要啟動一個 Service 的時候,一般都是在 Activity 中通過 startService() 來啟動:

// frameworks/base/core/java/android/app/ActivityManager.javapublic class ActivityManager {@UnsupportedAppUsagepublic static IActivityManager getService() {return IActivityManagerSingleton.get();}@UnsupportedAppUsageprivate static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};}

但是我們在 Activity 源碼中并沒有實現 startService() 方法,那它在哪里被調用的?找不到我們就去 Activity 的父類中找。

// frameworks/base/core/java/android/app/Activity.javapublic class Activity extends ContextThemeWrapperimplements LayoutInflater.Factory2,Window.Callback, KeyEvent.Callback,OnCreateContextMenuListener, ComponentCallbacks2,Window.OnWindowDismissedCallback, WindowControllerCallback,AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {}// frameworks/base/core/java/android/view/ContextThemeWrapper.javapublic class ContextThemeWrapper extends ContextWrapper {}// frameworks/base/core/java/android/content/ContextWrapper.java public class ContextWrapper extends Context {}

Activity 繼承了 ContextThemeWrapper 類, ContextThemeWrapper 又繼承了 ContextWrapper類, ContextWrapper 又繼承了 Context 類。

ContextWrapper.startService()

在 ContextWrapper 中實現了 startService() 方法:

// frameworks/base/core/java/android/app/ActivityManager.javapublic class ActivityManager {@UnsupportedAppUsagepublic static IActivityManager getService() {return IActivityManagerSingleton.get();}@UnsupportedAppUsageprivate static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};}

所以 startService() 方法其實是由 ContextWrapper 實現的,緊接著又調用了 mBase.startService() 方法, mBase 對象是 Context 的子類 ContextImpl ,所以調用最終進入 ContextImpl類的 startService() 方法。

ContextImpl.startService()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.javapublic final class ActiveServices {ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)throws TransactionTooLargeException {return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,callingPackage, userId, false);}ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,int callingPid, int callingUid, boolean fgRequired, String callingPackage,final int userId, boolean allowBackgroundActivityStarts)throws TransactionTooLargeException {... ...// 解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相關內容信息ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType, callingPackage,callingPid, callingUid, userId, true, callerFg, false, false);if (res == null) {return null;}... ...ServiceRecord r = res.record;... ...// 調用 startServiceInnerLocked() 方法ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);return cmp;}}

ActivityManager.getService()

// frameworks/base/core/java/android/app/ActivityManager.javapublic class ActivityManager {@UnsupportedAppUsagepublic static IActivityManager getService() {return IActivityManagerSingleton.get();}@UnsupportedAppUsageprivate static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};}

ActivityManagerService.startService()

接下來就執行到 ActivityManagerService 的 startService() 方法:

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.javapublic final class ActiveServices {private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException {... ...try {... ...app.thread.scheduleCreateService(r, r.serviceInfo,mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), app.getReportedProcState());... ...}... ...}}

ActiveServices.startServiceLocked()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.javapublic final class ActiveServices {ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)throws TransactionTooLargeException {return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,callingPackage, userId, false);}ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,int callingPid, int callingUid, boolean fgRequired, String callingPackage,final int userId, boolean allowBackgroundActivityStarts)throws TransactionTooLargeException {... ...// 解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相關內容信息ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType, callingPackage,callingPid, callingUid, userId, true, callerFg, false, false);if (res == null) {return null;}... ...ServiceRecord r = res.record;... ...// 調用 startServiceInnerLocked() 方法ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);return cmp;}}

通過 retrieveServiceLocked() 方法來解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相關內容信息。

當解析完 Service 的 intent-filter 相關內容信息后,解析的結果會保存在 res.record 變量中。而 res 變量是一個 ServiceLookupResult 類型的對象,它的 record 變量則是一個 ServiceRecord 類型對象,用來表示一個 Service 。

ActiveServices.startServiceInnerLocked()

ActiveServices 的 startServiceLocked() 方法最后調用了 startServiceInnerLocked() 方法:

//<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.android.documentsui"><applicationandroid:name=".DocumentsApplication"android:label="@string/app_label"android:icon="@drawable/app_icon"android:supportsRtl="true"android:allowBackup="true"android:backupAgent=".prefs.BackupAgent"android:fullBackupOnly="false"><!-- Run FileOperationService in a separate process so that we can use FileLock class towait until jumbo clip is done writing to disk before reading it. See ClipStorage fordetails. --><serviceandroid:name=".services.FileOperationService"android:exported="false"android:process=":com.android.documentsui.services"></service></application> </manifest>

ActiveServices.bringUpServiceLocked()

調用 bringUpServiceLocked() 方法進一步處理:

// frameworks/base/core/java/android/app/ActivityThread.javapublic final class ActivityThread extends ClientTransactionHandler {class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {case CREATE_SERVICE:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));handleCreateService((CreateServiceData)msg.obj); // 調用 handleCreateService() 方法Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;}}} }

bringUpServiceLocked() 方法首先通過 getProcessRecordLocked() 方法去獲取 app 對象,它是一個 ProcessRecord 類型的對象,如果它不為空,說明 Service 要運行的進程已經存在。

Service 運行的進程有兩種:

(1)一種是默認的,即運行在 Activity 啟動 Service 的那個進程里,也就是說在哪個進程里調用了 startService() 方法,啟動的 service 就運行在哪個進程里。

(2)一種是給 Service 一個單獨的進程運行,比如在 AndroidManifest 文件里配置了如下內容:

//<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.android.documentsui"><applicationandroid:name=".DocumentsApplication"android:label="@string/app_label"android:icon="@drawable/app_icon"android:supportsRtl="true"android:allowBackup="true"android:backupAgent=".prefs.BackupAgent"android:fullBackupOnly="false"><!-- Run FileOperationService in a separate process so that we can use FileLock class towait until jumbo clip is done writing to disk before reading it. See ClipStorage fordetails. --><serviceandroid:name=".services.FileOperationService"android:exported="false"android:process=":com.android.documentsui.services"></service></application> </manifest>

在這段配置里有 android:process="xxx" 聲明,這個聲明用來實現 service 單獨運行在 "xxx" 進程里。這樣做的好處是, 即使應用程序無法工作,由于 service 單獨運行在一個進程里,所以會繼續工作 。

回到前面的方法,如果變量 app 為空,就代表 service 要運行的進程還沒有啟動,于是調用 startProcessLocked() 方法去啟動一個新的進程。

如果 app 不為空,采用默認的方式啟動 Service,最終調用到 realStartServiceLocked() 方法:

ActiveServices.realStartServiceLocked()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.javapublic final class ActiveServices {private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException {... ...try {... ...app.thread.scheduleCreateService(r, r.serviceInfo,mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), app.getReportedProcState());... ...}... ...}}

在這個方法中,app 對象的 thread 變量是一個 ApplicationThread Binder 對象,調用它的scheduleCreateService() 方法之后,會進入客戶端的 ActivityThread 中。

ActivityThread.scheduleCreateService()

// frameworks/base/core/java/android/app/ActivityThread.javapublic final class ActivityThread extends ClientTransactionHandler {// ApplicationThread 是一個 Binderprivate class ApplicationThread extends IApplicationThread.Stub {public final void scheduleCreateService(IBinder token,ServiceInfo info, CompatibilityInfo compatInfo, int processState) {updateProcessState(processState, false);CreateServiceData s = new CreateServiceData();s.token = token;s.info = info;s.compatInfo = compatInfo;sendMessage(H.CREATE_SERVICE, s);}}}

ApplicationThread 的 scheduleCreateService() 方法通過調用 sendMessage() 方法來發送一個 msg 消息 ,當 Handler 接收到了 msg 消息之后,它會調用 handleCreateService() 方法來做進一步處理。

H.handleMessage()

// frameworks/base/core/java/android/app/ActivityThread.javapublic final class ActivityThread extends ClientTransactionHandler {class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {case CREATE_SERVICE:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));handleCreateService((CreateServiceData)msg.obj); // 調用 handleCreateService() 方法Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;}}} }

ActivityThread.handleCreateService()

// frameworks/base/core/java/android/app/ActivityThread.javapublic final class ActivityThread extends ClientTransactionHandler {private void handleCreateService(CreateServiceData data) {... ...LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);Service service = null;try {java.lang.ClassLoader cl = packageInfo.getClassLoader();service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);} catch (Exception e) {if (!mInstrumentation.onException(service, e)) {throw new RuntimeException("Unable to instantiate service " + data.info.name+ ": " + e.toString(), e);}}try {if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);ContextImpl context = ContextImpl.createAppContext(this, packageInfo);context.setOuterContext(service);Application app = packageInfo.makeApplication(false, mInstrumentation);service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());service.onCreate(); // 進入 Service.onCreate() 方法mServices.put(data.token, service);try {ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}} catch (Exception e) {if (!mInstrumentation.onException(service, e)) {throw new RuntimeException("Unable to create service " + data.info.name+ ": " + e.toString(), e);}}}}

在 ActivityThread 類的 handleCreateService() 方法中,首先通過 ClassLoader 類把 Service 加載進來,而參數 data.info.name 表示這個 Service 的名字, instantiateService() 方法是創建一個 Service 實例。接著, 創建一個 Context 對象 ,作為上下文環境之用。

handleCreateService() 方法最后調用了 service 的 onCreate() 方法 ,當這個方法被調用之后, 就會進入應用程序里 Service 的 onCreate() 方法 。

至此,Service 的啟動就分析完畢,這個過程與啟動 Activity 相比簡單了很多。

總結

看到最后,希望這篇文章能幫你梳理清楚 “Service 的啟動流程” 。

我整理了一些Activity的資料,如果你有需要可以私信我獲取

還有Android學習PDF+架構視頻+面試文檔+源碼筆記,高級架構技術進階腦圖、Android開發面試專題資料,高級進階架構資料這些都是我閑暇還會反復翻閱的精品資料

總之也是在這里幫助大家學習提升進階,也節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習

如果你有需要的話,可以點贊+評論,關注我,然后私信我【學習】獲取

總結

以上是生活随笔為你收集整理的service启动activity_「 Android 10 四大组件 」系列—Service 的 quot; 启动流程 quot;的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日日夜夜艹 | 日本人dh亚洲人ⅹxx | 亚洲青青操 | 久久久久久久久久久丰满 | 图片一区二区 | 青青草视频免费观看 | bbbbbbbbb毛片大片按摩 | a级无遮挡超级高清-在线观看 | 国产91精品久久久久久久 | 成人免费看片在线观看 | 国产3级在线 | 成人av网站大全 | 色综合久久久无码中文字幕波多 | 亚洲精品国产精品乱码不卡 | 一级黄色a级片 | 欧美肉丝袜videos办公室 | 人与禽性7777777 | 亚洲性综合| 日韩一区二区久久 | 国产亚洲视频在线 | 国产精品久久久久久一区 | 免费日韩一级片 | 国产日韩一区二区在线观看 | 一区二区在线免费视频 | 舌奴调教日记 | 天堂一二三区 | 在线视频二区 | 欧美国产成人精品一区二区三区 | 欧美一区二区三区婷婷 | 国产激情对白 | 波多野结衣视频一区二区 | 怡红院最新网址 | 99热这里只有精 | a级一a一级在线观看 | 对白超刺激精彩粗话av | 亚洲视频中文字幕 | 视频一区二区中文字幕 | 欧美色图狠狠干 | 国产又粗又猛又色 | 91精品欧美一区二区三区 | 寡妇高潮一级视频免费看 | 91精品91久久久中77777 | 国产一级做a爱片久久毛片a | 亚洲欧美日韩在线不卡 | 国产精品免费视频一区二区三区 | 操模特 | 国产视频福利在线观看 | 天堂在线精品视频 | 午夜精品影院 | 久久无码人妻一区二区三区 | 成人精品视频一区 | 夜色在线视频 | 欧美三级视频在线观看 | 桃色视频网 | 国产夫妻在线 | 在线成人国产 | 欧美日韩高清在线 | 精品国产a| 深夜老司机福利 | 国产99999 | 最近免费中文字幕 | 日本在线高清视频 | 一本大道综合伊人精品热热 | 操老女人视频 | 桃花色综合影院 | 国产夫妻自拍av | 免费看成人aa片无码视频羞羞网 | 亚洲另类色综合网站 | 久久久久国产精品人妻 | 91黄色国产| 落日余晖| 人人草人人 | 色片免费看 | 伊人激情在线 | 亚洲一区二区播放 | 97人妻一区二区精品免费视频 | 朝桐光一区二区三区 | 欧美理伦 | 影音先锋二区 | 涩天堂| 在线亚洲欧美 | 中文字幕在线观看一区二区三区 | 官场艳妇疯狂性关系 | 亚洲砖区免费 | 美女网站免费黄 | 午夜免费福利在线 | 国产欧美中文字幕 | 放荡的少妇2欧美版 | 少妇人妻偷人精品无码视频 | 水蜜桃av无码| 91亚洲精品久久久蜜桃 | 美女黄色录像 | 91久久精品国产91久久性色tv | 特大黑人巨交吊性xx | 欧美日韩高清一区 | 日本h在线观看 | 欧美在线播放一区二区 | 欧美日韩久久婷婷 | 东北女人av |