1. 概述
Android插件化架構(gòu)穆碎,目前第三方的框架比較多,早幾年自己用的是DL框架职恳,這個框架的源碼比較簡單主要用的是靜態(tài)代理所禀。如果我們自己要去寫一個插件化架構(gòu)框架那要解決的問題會分為幾個方面,類的加載放钦,資源和布局的加載色徘,廣播的管理方式,Activity的加載和生命周期管理操禀,Service的插件化褂策,ContentProvider的插件化等等等等,反正加載一個沒有運(yùn)行的app到主程序颓屑,需要解決的問題基本就這么多斤寂,如果能夠一一解決那么就可以實(shí)現(xiàn)插件化了。
內(nèi)涵段子項(xiàng)目部分我們實(shí)現(xiàn)幾個揪惦,然后介紹一個360開源框架DroidPlugin原理一致遍搞,后面我們再一一實(shí)現(xiàn),那么這一期實(shí)現(xiàn)什么呢丹擎?我們需要啟動插件APP那么就需要啟動里面的Activity,這些Activity事先是不會在主工程的AndroidManifest.xml中配置尾抑,啟動一個沒有注冊的Activity肯定會報錯,我們是否可以想個辦法去繞過系統(tǒng)的檢測蒂培,讓沒有在AndroidManifest.xml中配置的Activity照樣可以啟動呢再愈?
看源碼的時候我們其實(shí)時常強(qiáng)調(diào)一定要帶著思想,要解決這么個問題我們肯定需要清楚的知道系統(tǒng)啟動Activity的具體流程护戳,當(dāng)然可以直接去了解為什么報錯翎冲,這里我們還是把啟動流程全部走一遍,也方便以后開發(fā)中再遇到什么問題媳荒。
2. Activity啟動流程源碼分析
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
來到Instrumentation中的execStartActivity方法
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
// 檢測結(jié)果也就是否正常
public static void checkStartActivityResult(int res, Object intent) {
if (res >= ActivityManager.START_SUCCESS) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
// 在這里就會報各種錯抗悍,AndroidManifest.xml中沒有配置的錯就出現(xiàn)在這
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case ActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
case ActivityManager.START_NOT_VOICE_COMPATIBLE:
throw new SecurityException(
"Starting under voice control not allowed for: " + intent);
case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
throw new IllegalStateException(
"Session calling startVoiceActivity does not match active session");
case ActivityManager.START_VOICE_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start voice activity on a hidden session");
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
ActivityManagerNative.getDefault().startActivity又是一個進(jìn)程間的通信驹饺,如果不了解IPC的請移步Android進(jìn)程間的通信 - IPC(機(jī)制)Binder的原理和源碼閱讀,來到ActivityManagerService中的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());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);
}
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
// PackageManagerService-----> 掃描app缴渊,注冊組件
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask);
}
final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
// 驗(yàn)證intent赏壹、Class、Permission等
// 保存將要啟動的Activity的Record
err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true, options, inTask);
return err;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
// 檢查將要啟動的Activity的launchMode和啟動Flag
// 根據(jù)launcheMode和Flag配置task
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask);
// 舉一個例子 SingleTop
if (dontStart) {
top.deliverNewIntentLocked(
mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
// Don't use mStartActivity.task to show the toast. We're not starting a new activity
// but reusing 'top'. Fields in mStartActivity may not be fully initialized.
mSupervisor.handleNonResizableTaskIfNeeded(
top.task, preferredLaunchStackId, topStack.mStackId);
return START_DELIVERED_TO_TOP;
}
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
}
進(jìn)入ActvityStack中的startActivityLocked()方法
// 任務(wù)棧歷史棧配置
final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
ActivityOptions options) {
if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
// 加入棧頂 管理?xiàng)? insertTaskAtTop(rTask, r);
// 管顯示
mWindowManager.moveTaskToTop(taskId);
}
if (!newTask) {
// 不是一個新的Task
task.addActivityToTop(r);
r.putInHistory();
addConfigOverride(r, task);
}
}
進(jìn)入ActivityStack的resumeTopActivityInnerLocked()方法
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// Find the first activity that is not finishing.
final ActivityRecord next = topRunningActivityLocked();
// The activity may be waiting for stop, but that is no longer
// appropriate for it.
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
}
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean dontWait) {
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
// 暫停Activity
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
}
completePauseLocked(false, resuming);
}
進(jìn)入ApplicationThread的schedulePauseActivity()方法
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
public void handleMessage(Message msg) {
switch (msg.what) {
...
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
//...
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
//...
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState, String reason) {
// ...
performPauseActivityIfNeeded(r, reason);
}
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
// ...
mInstrumentation.callActivityOnPause(r.activity);
}
進(jìn)入Instrumentation的callActivityOnPause()方法
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
進(jìn)入Activity的performPause()方法
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
// 調(diào)用onPause()暫停方法
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
總算是回調(diào)到了Activity的onPause方法衔沼,哈哈還是挺簡單的蝌借,Activity生命周期中的onPause方法終于被我們找到了。也就是說我們在啟動一個Activity的時候最先被執(zhí)行的是棧頂?shù)腁ctivity的onPause方法指蚁。我們對Activity這些生命周期早已背得滾瓜爛熟菩佑。接著往下看然后回到我們ApplicationThread的handlePauseActivity()方法中的ActivityManagerNative.getDefault().activityPaused(token);進(jìn)入ActivityManagerService中的activityPaused()方法
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
進(jìn)入ActivityStack中的activityPausedLocked()方法
final void activityPausedLocked(IBinder token, boolean timeout){
completePauseLocked(true, null);
}
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
}
}
進(jìn)入ActivityStackSupervisor中的resumeFocusedStackTopActivityLocked()方法
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
進(jìn)入ActivityStack中的resumeTopActivityUncheckedLocked()方法
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
result = resumeTopActivityInnerLocked(prev, options);
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// 這個方法我們已經(jīng)很熟悉了
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
進(jìn)入ActivityStackSupervisor中的startSpecificActivityLocked()方法
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) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
// 真的要啟動Activity了
realStartActivityLocked(r, app, 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.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// scheduleLaunchActivity 啟動
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
}
進(jìn)入ApplicationThread中的scheduleLaunchActivity()方法
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
// Initialize before creating the activity
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
// The activity manager actually wants this one to start out paused, because it
// needs to be visible but isn't in the foreground. We accomplish this by going
// through the normal startup (because activities expect to go through onResume()
// the first time they run, before their window is displayed), and then pausing it.
// However, in this case we do -not- need to do the full pause cycle (of freezing
// and such) because the activity manager assumes it can just retain the current
// state it has.
performPauseActivityIfNeeded(r, reason);
// We need to keep around the original state, in case we need to be created again.
// But we only do this for pre-Honeycomb apps, which always save their state when
// pausing, so we can not have them save their state when restarting from a paused
// state. For HC and later, we want to (and can) let the state be saved as the
// normal part of stopping the activity.
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
3. Activity啟動流程總結(jié)
剛開始去看估計要看個一兩天才會有所收貨,其實(shí)看源碼要么是為了解決問題要么是為了學(xué)習(xí)凝化,否則還是不要輕易的進(jìn)入這趟渾水里面稍坯,代碼太多了沒有思想會蒙的。首先可以大致先走一遍流程搓劫,然后再去抓細(xì)節(jié)瞧哟,比如怎么分配棧的,怎么處理啟動模式的糟把,怎么創(chuàng)建Activity的绢涡,怎么調(diào)用生命周期的,怎么傳遞序列化對象參數(shù)的等等......
看了源碼之后我們不得不佩服Google的工程師遣疯,寫的代碼可擴(kuò)展真的很不錯雄可,要是換做一般人版本迭代幾次代碼就改不動了,得要重新架構(gòu)重新寫缠犀,這也是我們學(xué)習(xí)的方式数苫,源碼其實(shí)是最好的書籍。這里有好幾個思想辨液,C/S架構(gòu)思想就是服務(wù)思想虐急,模塊化思想,分層次思想等等...
最后我們看一下在啟動流程中出現(xiàn)的幾個主要的類都分別有什么功能:
- ** ActivityManagerService** 組件通信系統(tǒng)核心管理類 (ActivityManagerNative)IPC通信
- ** ActivityStackSupervisor** 管理整個手機(jī)的Activity任務(wù)棧
- ActivityStack Activity棧(任務(wù)棧)
- ** PackageManagerService** 主要負(fù)責(zé)對系統(tǒng)的apk進(jìn)行管理滔迈,不管是系統(tǒng)apk(/system/app)止吁,還是我們手工安裝上去的,系統(tǒng)所有的apk都是由其管理的燎悍。
- ** ActivityThread** Activity的入口是onCreate方法敬惦,Android上一個應(yīng)用的入口是ActivityThread。和普通的Java類一樣有一個main方法谈山。用于控制與管理一個應(yīng)用進(jìn)程的主線程的操作俄删,包括管理與處理activity manager發(fā)送過來的關(guān)于activities、廣播以及其他的操作請求
ActivityManagerService和ActivityStack位于同一個進(jìn)程中,而ApplicationThread和ActivityThread位于另一個進(jìn)程中畴椰。其中臊诊,ActivityManagerService是負(fù)責(zé)管理Activity的生命周期的,ActivityManagerService還借助ActivityStack是來把所有的Activity按照后進(jìn)先出的順序放在一個堆棧中斜脂;對于每一個應(yīng)用程序來說抓艳,都有一個ActivityThread來表示應(yīng)用程序的主進(jìn)程,而每一個ActivityThread都包含有一個ApplicationThread實(shí)例秽褒,它是一個Binder對象壶硅,負(fù)責(zé)和其它進(jìn)程進(jìn)行通信。
這么痛苦的去讀源碼到底有什么用呢销斟?那么結(jié)合動態(tài)代碼設(shè)計模式以及Activity的啟動流程,我們就可以嘗試去攔截Activity的啟動流程椒舵,讓沒有在AndroidMainfest.xml中注冊的Activity也能啟動并且不報錯蚂踊,這樣我們就算是跨出了插件化架構(gòu)的第一步了,如果你不去了解Activity啟動流程那么就是然并卵笔宿。
所有分享大綱:2017Android進(jìn)階之路與你同行