色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

詳解Android Activity的啟動(dòng)流程

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

activity啟動(dòng)的流程分為兩部分:一是在activity中通過(guò)startActivity(Intent intent)方法啟動(dòng)一個(gè)Activity;二是我們?cè)谧烂嫱ㄟ^(guò)點(diǎn)擊應(yīng)用圖標(biāo)啟動(dòng)一個(gè)App然后顯示Activity;第二種方式相較于第一種方式更加全面,所以本文會(huì)以第二種流程來(lái)分析。

簡(jiǎn)要

我們手機(jī)的桌面是一個(gè)叫做Launcher的Activity,它羅列了手機(jī)中的應(yīng)用圖標(biāo),圖標(biāo)中包含安裝apk時(shí)解析的應(yīng)用默認(rèn)啟動(dòng)頁(yè)等信息。在點(diǎn)擊應(yīng)用圖標(biāo)時(shí),即將要啟動(dòng)的App和Launcher、AMS、Zygote所屬進(jìn)程不同所以涉及到Launcher與AMS,AMS與Zygote,AMS與新App這四者多次通信,才會(huì)啟動(dòng)一個(gè)App,然后再啟動(dòng)Activity,整體的時(shí)序圖如下:

詳解Android Activity的啟動(dòng)流程

接下來(lái)根據(jù)源碼來(lái)梳理一下流程。

1.Launcher向AMS發(fā)送啟動(dòng)Activity

Launcher本身是一個(gè)Activity,在用戶點(diǎn)擊應(yīng)用圖標(biāo)時(shí),調(diào)用startActivitySafely方法,最后調(diào)用到Activity.startActivity(),函數(shù)調(diào)用如下

Launcher.java public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { ... //標(biāo)記在新的棧啟動(dòng) 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表明不需要知道是否啟動(dòng)成功 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); ... }

每個(gè)Activity都持有Instrumentation對(duì)象,通過(guò)它的execStartActivity函數(shù)來(lái)繼續(xù)完成啟動(dòng)Activity的流程,這個(gè)函數(shù)中傳入了mMainThread.getApplicationThread(),它獲取到的是ActivityThread的內(nèi)部類ApplicationThread,這是一個(gè)Binder對(duì)象,之后AMS通過(guò)此對(duì)象與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開(kāi)始向AMS通信,由于在不同的進(jìn)程所以需要通過(guò)Binder來(lái)通信,IActivityTaskManager是一個(gè)代理AMS端Binder的對(duì)象,之后AMS開(kāi)始startActivity。 到這里L(fēng)auncher向AMS請(qǐng)求啟動(dòng)一個(gè)Activity的流程就結(jié)束了。

2.AMS啟動(dòng)Activity并通知Launcher進(jìn)入Paused狀態(tài)

現(xiàn)在的流程是在AMS中,也就是另一個(gè)進(jìn)程中,上一步通過(guò)代理調(diào)用到AMS的startActivity方法,接下來(lái)的調(diào)用如下:

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); }

上面幾步主要是做權(quán)限檢查

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

startPausingLocked方法主要是通知Launcher進(jìn)入Paused狀態(tài),在它進(jìn)入這個(gè)狀態(tài)后,在ActivityStackSupervisor.startSpecificActivity方法判斷新的App進(jìn)程狀態(tài)做出不同響應(yīng),如下:

ActivityStackSupervisor.javavoid startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) { // 獲取要啟動(dòng)的Activity進(jìn)程信息 final WindowProcessController wpc = mService.getProcessController(r.processName, r.info.applicationInfo.uid); boolean knownToBeDead = false; //如果進(jìn)程存在且有進(jìn)程中有線程存在 就是啟動(dòng)一個(gè)同應(yīng)用的Activity(普通Activity就在此執(zhí)行) 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; }//否則通過(guò)AMS向Zygote進(jìn)程請(qǐng)求創(chuàng)建新的進(jìn)程 r.notifyUnknownVisibilityLaunchedForKeyguardTransition(); final boolean isTop = andResume && r.isTopRunningActivity(); mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? 'top-activity' : 'activity');}

截止到這里完成了Launcher和AMS的通信,以及AMS和Zygote進(jìn)程的通信,接下來(lái)我們要?jiǎng)?chuàng)建要啟動(dòng)的App的線程,即ActivityThread。

3.新的進(jìn)程啟動(dòng),ActivityThread的main函數(shù)入口

上一部分Zygote啟動(dòng)新的進(jìn)程時(shí)標(biāo)記ActivityThread.main函數(shù),在Zygote創(chuàng)建好新進(jìn)程后通過(guò)反射調(diào)用此方法,現(xiàn)在處于新App的進(jìn)程中。

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()); ... }

這里主要是創(chuàng)建了Looper和ActivityThread對(duì)象,然后將當(dāng)前應(yīng)用ApplicationThread注冊(cè)到AMS中,ApplicationThread是ActivityThread的內(nèi)部類實(shí)現(xiàn)了IApplicationThread.Stub用此對(duì)象可跨進(jìn)程通信,上面的代碼邏輯分兩步,第一步,在AMS綁定ApplicationThread時(shí),發(fā)送了一個(gè)H.BIND_APPLICATION的Message,在Handler中處理該消息時(shí)調(diào)用了Application的onCreate方法,第二步,在mAtmInternal的attachApplication層層調(diào)用到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線程已經(jīng)啟動(dòng)并且綁定了Application。

4.創(chuàng)建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); //執(zhí)行clientTransaction mService.getLifecycleManager().scheduleTransaction(clientTransaction); ...}

ClientTransaction管理了Activity的啟動(dòng)信息,由ClientLifecycleManager執(zhí)行,scheduleTransaction方法中發(fā)送了EXECUTE_TRANSACTION的消息給ActivityThread的H類處理,然后執(zhí)行TransactionExecutor.execute(),之后執(zhí)行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 */); }

接下來(lái)由ActivityThread來(lái)處理后續(xù)操作

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方法中主要做了以下幾件事:

創(chuàng)建要啟動(dòng)activity的上下文環(huán)境 通過(guò)Instrumentation的newActivity方法,以反射形式創(chuàng)建activity實(shí)例 如果Application不存在的話會(huì)創(chuàng)建Application并調(diào)用Application的onCreate方法 初始化Activity,創(chuàng)建Window對(duì)象(PhoneWindow)并實(shí)現(xiàn)Activity和Window相關(guān)聯(lián) 通過(guò)Instrumentation調(diào)用Activity的onCreate方法 總結(jié)

根Activity整體上學(xué)習(xí)意義較大,建議從整體流程入手,遇到流程不通時(shí)也可以debug。 Activity的整體啟動(dòng)流程:

點(diǎn)擊圖標(biāo),Launcher向AMS請(qǐng)求啟動(dòng)該App AMS反饋收到啟動(dòng)請(qǐng)求,并告知Launcher進(jìn)入pause狀態(tài) Launcher進(jìn)入Paused狀態(tài)并告知AMS AMS檢測(cè)新的App是否已啟動(dòng),否則通知Zygote創(chuàng)建新的進(jìn)程并啟動(dòng)ActivityThread.main() 應(yīng)用進(jìn)程啟動(dòng)ActivityThread ActivityThread中H處理需要啟動(dòng)Activity的請(qǐng)求消息

以上就是詳解Android Activity的啟動(dòng)流程的詳細(xì)內(nèi)容,更多關(guān)于Android Activity的啟動(dòng)流程的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Android
相關(guān)文章:
主站蜘蛛池模板: 中文字幕或区 | 国产日韩亚洲不卡高清在线观看 | 亚洲精品国产第一区第二区国 | 国产一区二区三区免费大片天美 | 在线观看香蕉免费啪在线观看 | 欧洲欧美成人免费大片 | 99久久伊人一区二区yy5o99 | 亚州免费一级毛片 | 毛片特黄| 国产黄色三级 | 我们2018在线完整免费观看 | 成年人毛片网站 | 日本一级毛片免费播放 | 一区二区影视 | 精品国产香港三级 | 亚洲高清在线观看看片 | 一区二区三区观看 | 成在线人永久免费播放视频 | 天堂一区二区三区在线观看 | 黄色美女视频 | 日产乱码精品一二三区 | 国产成a人片在线观看视频 国产成版人视频网站免费下 | 国产在线91区精品 | 高清一区二区三区免费 | 亚洲精彩| 国产一区二区三区在线观看影院 | 免费观看国产网址你懂的 | 成年女人在线观看片免费视频 | 国产三级香港在线观看 | 欧美一级特黄aa大片 | www一级片 | 国产在线视频专区 | 男女乱淫真视频免费观看 | 亚洲不卡一区二区三区在线 | 成年女人色毛片免费 | 嫩草一区二区三区四区乱码 | 亚洲日本一区二区三区 | 特级深夜a级毛片免费观看 特级生活片 | 狠狠色丁香婷婷综合小时婷婷 | 美女张开大腿让男人捅 | 亚洲人成亚洲人成在线观看 |