电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

詳解Android Activity的啟動流程

瀏覽:5日期:2022-09-20 14:45:17
前言

activity啟動的流程分為兩部分:一是在activity中通過startActivity(Intent intent)方法啟動一個Activity;二是我們在桌面通過點擊應用圖標啟動一個App然后顯示Activity;第二種方式相較于第一種方式更加全面,所以本文會以第二種流程來分析。

簡要

我們手機的桌面是一個叫做Launcher的Activity,它羅列了手機中的應用圖標,圖標中包含安裝apk時解析的應用默認啟動頁等信息。在點擊應用圖標時,即將要啟動的App和Launcher、AMS、Zygote所屬進程不同所以涉及到Launcher與AMS,AMS與Zygote,AMS與新App這四者多次通信,才會啟動一個App,然后再啟動Activity,整體的時序圖如下:

詳解Android Activity的啟動流程

接下來根據源碼來梳理一下流程。

1.Launcher向AMS發送啟動Activity

Launcher本身是一個Activity,在用戶點擊應用圖標時,調用startActivitySafely方法,最后調用到Activity.startActivity(),函數調用如下

Launcher.java public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { ... //標記在新的棧啟動 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ... startActivity(intent, optsBundle); ... }Activity.java @Override public void startActivity(Intent intent) { this.startActivity(intent, null); } @Override public void startActivity(Intent intent, @Nullable Bundle options) { ... if (options != null) { //-1為requestCode表明不需要知道是否啟動成功 startActivityForResult(intent, -1, options); } else { startActivityForResult(intent, -1); } } public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { ... Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken,this,intent, requestCode, options); ... }

每個Activity都持有Instrumentation對象,通過它的execStartActivity函數來繼續完成啟動Activity的流程,這個函數中傳入了mMainThread.getApplicationThread(),它獲取到的是ActivityThread的內部類ApplicationThread,這是一個Binder對象,之后AMS通過此對象與App的通信。

Instrumentation.javapublic ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { ...int result = ActivityTaskManager.getService().startActivity(whoThread,who.getBasePackageName(), who.getAttributionTag(),intent,intent.resolveTypeIfNeeded(who.getContentResolver()), token,target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); ...}ActivityTaskManager.javapublic static IActivityTaskManager getService() { return IActivityTaskManagerSingleton.get();} private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton = new Singleton<IActivityTaskManager>() { @Override protected IActivityTaskManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); return IActivityTaskManager.Stub.asInterface(b); } }};

這一步Launcher開始向AMS通信,由于在不同的進程所以需要通過Binder來通信,IActivityTaskManager是一個代理AMS端Binder的對象,之后AMS開始startActivity。 到這里Launcher向AMS請求啟動一個Activity的流程就結束了。

2.AMS啟動Activity并通知Launcher進入Paused狀態

現在的流程是在AMS中,也就是另一個進程中,上一步通過代理調用到AMS的startActivity方法,接下來的調用如下:

ActivityTaskManagerService.java @Override public final int startActivity(IApplicationThread caller, String callingPackage, String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } @Override public int startActivityAsUser(IApplicationThread caller, String callingPackage, String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId, true /*validateIncomingUser*/); } private int startActivityAsUser(IApplicationThread caller, String callingPackage, @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { ... userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), 'startActivityAsUser'); return getActivityStartController().obtainStarter(intent, 'startActivityAsUser') .setCaller(caller) .setCallingPackage(callingPackage) .setCallingFeatureId(callingFeatureId) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setUserId(userId) .execute(); } ActivityStarter obtainStarter(Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); }

上面幾步主要是做權限檢查

ActivityStarter.java int execute() { ... res = executeRequest(mRequest); ... }//層層調用會到下面這個方法ActivityStack.java private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { ... if (mResumedActivity != null) { pausing |= startPausingLocked(userLeaving, false , next); } ... mStackSupervisor.startSpecificActivity(next, true, false); ... }

startPausingLocked方法主要是通知Launcher進入Paused狀態,在它進入這個狀態后,在ActivityStackSupervisor.startSpecificActivity方法判斷新的App進程狀態做出不同響應,如下:

ActivityStackSupervisor.javavoid startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) { // 獲取要啟動的Activity進程信息 final WindowProcessController wpc = mService.getProcessController(r.processName, r.info.applicationInfo.uid); boolean knownToBeDead = false; //如果進程存在且有進程中有線程存在 就是啟動一個同應用的Activity(普通Activity就在此執行) if (wpc != null && wpc.hasThread()) { try { realStartActivityLocked(r, wpc, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, 'Exception when starting activity ' + r.intent.getComponent().flattenToShortString(), e); } // If a dead object exception was thrown -- fall through to // restart the application. knownToBeDead = true; }//否則通過AMS向Zygote進程請求創建新的進程 r.notifyUnknownVisibilityLaunchedForKeyguardTransition(); final boolean isTop = andResume && r.isTopRunningActivity(); mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? 'top-activity' : 'activity');}

截止到這里完成了Launcher和AMS的通信,以及AMS和Zygote進程的通信,接下來我們要創建要啟動的App的線程,即ActivityThread。

3.新的進程啟動,ActivityThread的main函數入口

上一部分Zygote啟動新的進程時標記ActivityThread.main函數,在Zygote創建好新進程后通過反射調用此方法,現在處于新App的進程中。

ActivityThread.java public static void main(String[] args) { ... Looper.prepareMainLooper();... ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq);... Looper.loop();... } private void attach(boolean system, long startSeq) { final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ... }ActivityManagerService.java private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { ... thread.bindApplication(processName, appInfo, providerList, 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, app.mDisabledCompatChanges); ... didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); ... }

這里主要是創建了Looper和ActivityThread對象,然后將當前應用ApplicationThread注冊到AMS中,ApplicationThread是ActivityThread的內部類實現了IApplicationThread.Stub用此對象可跨進程通信,上面的代碼邏輯分兩步,第一步,在AMS綁定ApplicationThread時,發送了一個H.BIND_APPLICATION的Message,在Handler中處理該消息時調用了Application的onCreate方法,第二步,在mAtmInternal的attachApplication層層調用到ActivityStackSupervisor.realStartActivityLocked方法,整體如下:

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) { ... sendMessage(H.BIND_APPLICATION, data); } public void handleMessage(Message msg) { switch (msg.what) { case BIND_APPLICATION: AppBindData data = (AppBindData)msg.obj; handleBindApplication(data); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... }}private void handleBindApplication(AppBindData data) {...mInstrumentation.callApplicationOnCreate(app);...}

到這里為止,新的App線程已經啟動并且綁定了Application。

4.創建Activity

ActivityStackSupervisor.javaboolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException { ... final ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken); final DisplayContent dc = r.getDisplay().mDisplayContent; clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(), results, newIntents, dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(), r.assistToken, r.createFixedRotationAdjustmentsIfNeeded())); final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); //執行clientTransaction mService.getLifecycleManager().scheduleTransaction(clientTransaction); ...}

ClientTransaction管理了Activity的啟動信息,由ClientLifecycleManager執行,scheduleTransaction方法中發送了EXECUTE_TRANSACTION的消息給ActivityThread的H類處理,然后執行TransactionExecutor.execute(),之后執行handleLaunchActivity方法,如下

void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); ... } public void schedule() throws RemoteException { mClient.scheduleTransaction(this); } void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } class H extends Handler { ... public void handleMessage(Message msg) { ... case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); if (isSystem()) { transaction.recycle(); } break; ... } ... } public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { ... client.handleLaunchActivity(r, pendingActions, null /* customIntent */); }

接下來由ActivityThread來處理后續操作

public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... final Activity a = performLaunchActivity(r, customIntent); ... return a;}private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ContextImpl appContext = createBaseContextForActivity(r); ... java.lang.ClassLoader cl = appContext.getClassLoader(); activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); ... Application app = r.packageInfo.makeApplication(false, mInstrumentation); ... activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback, r.assistToken); ... activity.setTheme(theme); ... mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);}

performLaunchActivity方法中主要做了以下幾件事:

創建要啟動activity的上下文環境 通過Instrumentation的newActivity方法,以反射形式創建activity實例 如果Application不存在的話會創建Application并調用Application的onCreate方法 初始化Activity,創建Window對象(PhoneWindow)并實現Activity和Window相關聯 通過Instrumentation調用Activity的onCreate方法 總結

根Activity整體上學習意義較大,建議從整體流程入手,遇到流程不通時也可以debug。 Activity的整體啟動流程:

點擊圖標,Launcher向AMS請求啟動該App AMS反饋收到啟動請求,并告知Launcher進入pause狀態 Launcher進入Paused狀態并告知AMS AMS檢測新的App是否已啟動,否則通知Zygote創建新的進程并啟動ActivityThread.main() 應用進程啟動ActivityThread ActivityThread中H處理需要啟動Activity的請求消息

以上就是詳解Android Activity的啟動流程的詳細內容,更多關于Android Activity的啟動流程的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
主站蜘蛛池模板: MVR蒸发器厂家-多效蒸发器-工业废水蒸发器厂家-康景辉集团官网 | 网站建设-临朐爱采购-抖音运营-山东兆通网络科技 | 发电机组|柴油发电机组-批发,上柴,玉柴,潍柴,康明斯柴油发电机厂家直销 | 沉降天平_沉降粒度仪_液体比重仪-上海方瑞仪器有限公司 | 粘弹体防腐胶带,聚丙烯防腐胶带-全民塑胶 | 深圳标识制作公司-标识标牌厂家-深圳广告标识制作-玟璟广告-深圳市玟璟广告有限公司 | 上海噪音治理公司-专业隔音降噪公司-中广通环保 | 深圳宣传片制作-企业宣传视频制作-产品视频拍摄-产品动画制作-短视频拍摄制作公司 | 长沙一级消防工程公司_智能化弱电_机电安装_亮化工程专业施工承包_湖南公共安全工程有限公司 | 袋式过滤器,自清洗过滤器,保安过滤器,篮式过滤器,气体过滤器,全自动过滤器,反冲洗过滤器,管道过滤器,无锡驰业环保科技有限公司 | 环保袋,无纺布袋,无纺布打孔袋,保温袋,环保袋定制,环保袋厂家,环雅包装-十七年环保袋定制厂家 | 化工ERP软件_化工新材料ERP系统_化工新材料MES软件_MES系统-广东顺景软件科技有限公司 | 机床主轴维修|刀塔维修|C轴维修-常州翔高精密机械有限公司 | 广东恩亿梯电源有限公司【官网】_UPS不间断电源|EPS应急电源|模块化机房|电动汽车充电桩_UPS电源厂家(恩亿梯UPS电源,UPS不间断电源,不间断电源UPS) | 四川职高信息网-初高中、大专、职业技术学校招生信息网 | 杜甫仪器官网|实验室平行反应器|升降水浴锅|台式低温循环泵 | 东莞市踏板石餐饮管理有限公司_正宗桂林米粉_正宗桂林米粉加盟_桂林米粉加盟费-东莞市棒子桂林米粉 | 金环宇|金环宇电线|金环宇电缆|金环宇电线电缆|深圳市金环宇电线电缆有限公司|金环宇电缆集团 | 合肥废气治理设备_安徽除尘设备_工业废气处理设备厂家-盈凯环保 合肥防火门窗/隔断_合肥防火卷帘门厂家_安徽耐火窗_良万消防设备有限公司 | 雷达液位计_超声波风速风向仪_雨量传感器_辐射传感器-山东风途物联网 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 纸箱抗压机,拉力机,脂肪测定仪,定氮仪-山东德瑞克仪器有限公司 | 一体式钢筋扫描仪-楼板测厚仪-裂缝检测仪-泰仕特(北京) | 石英陶瓷,石英坩埚,二氧化硅陶瓷-淄博百特高新材料有限公司 | 吲哚菁绿衍生物-酶底物法大肠菌群检测试剂-北京和信同通科技发展有限公司 | 真空搅拌机-行星搅拌机-双行星动力混合机-广州市番禺区源创化工设备厂 | 欧美日韩国产一区二区三区不_久久久久国产精品无码不卡_亚洲欧洲美洲无码精品AV_精品一区美女视频_日韩黄色性爱一级视频_日本五十路人妻斩_国产99视频免费精品是看4_亚洲中文字幕无码一二三四区_国产小萍萍挤奶喷奶水_亚洲另类精品无码在线一区 | 圆盘鞋底注塑机_连帮鞋底成型注塑机-温州天钢机械有限公司 | 高温链条油|高温润滑脂|轴承润滑脂|机器人保养用油|干膜润滑剂-东莞卓越化学 | 电子天平-华志电子天平厂家| 浙江栓钉_焊钉_剪力钉厂家批发_杭州八建五金制造有限公司 | 【MBA备考网】-2024年工商管理硕士MBA院校/报考条件/培训/考试科目/提前面试/考试/学费-MBA备考网 | 微信聊天记录恢复_手机短信删除怎么恢复_通讯录恢复软件下载-快易数据恢复 | 步进驱动器「一体化」步进电机品牌厂家-一体式步进驱动 | 湖州织里童装_女童男童中大童装_款式多尺码全_织里儿童网【官网】-嘉兴嘉乐网络科技有限公司 | 镀锌钢格栅_热镀锌格栅板_钢格栅板_热镀锌钢格板-安平县昊泽丝网制品有限公司 | 气胀轴|气涨轴|安全夹头|安全卡盘|伺服纠偏系统厂家-天机传动 | 医院专用门厂家报价-医用病房门尺寸大全-抗菌木门品牌推荐 | 磁力加热搅拌器-多工位|大功率|数显恒温磁力搅拌器-司乐仪器官网 | 洗瓶机厂家-酒瓶玻璃瓶冲瓶机-瓶子烘干机-封口旋盖压盖打塞机_青州惠联灌装机械 | 洛阳永磁工业大吊扇研发生产-工厂通风降温解决方案提供商-中实洛阳环境科技有限公司 |