一、概述
话说Android中有四大组件:Activity、Service、BroadcastReceiver、ContentProvider。咱们最常接触也是用户直接感受到的便是Activity了,今日来就说说Android发动的履行进程和* @ B 8 X x作业原理。
Activity是一种 展现型组件,用于展现给用户一个能够交互的页面。Activity是Android中最重要的; % ) 0 : . p组件,对用户来说,一切的AM d v C i Q J Tctivity便是一个App的悉数,而其他组件用户是不能直接感知的。在开发层面,要发动一个Activity能够! g A ) Z b运用Intent,分显式和隐式,R x c 2 K而且还能够设z s Y置Activity的L b G , v K w [发动模式。
Android体系对四大组件都做了很大程度的封装,这样咱们能够快速运用组件。Activity的发动在体系封装后,变的极为简略,显现发动activity代码如下; Q ):
Intent intent = new Intent(this, TestActivity.class);
this.startActivity(iG F 4 * A N g Yntent);
这样就能够发动TestActivu y ~ &ity了,那么问题来了,
- 这个代码是怎样发动一个Activi? R d I lty的?
- 里边做了哪些作业?
- onCreate这些生命周期是何时履行的?
- Activity目标何时创立的?
- 视图是怎样处理以及何时可见的?
- 根activity(第7 T ,一个activity)又是怎样发动的?
那么为啥需求了解这些问题呢?不了解 ,平时开发好像也没啥问题啊。其实: i # _ 7 T u %不然,处理这些问题后,你会对Android体系有更深层次的理解,也会学习到体系源码优秀的规划。而且对处理一些高档问题g , M A c j和深化的性能优化问题有很大协助,是技能进阶的必要阶段。这就需求咱们经过阅m A i +读源码来整理这些问题,但w 8 M & n q j另一方面,体系源码是很庞大繁杂的,咱们需求带着问题抓住主流程,不能陷入代码细节——这是阅读体系源码以及其他第三方库源码的正确姿态。
这儿先给出 Activity发动 的 整体交互图:
其间创立运用进程的逻辑一般在发动根acU S y ctivity时会走到,一般activityt ^ / m b Y不触及Launcher和Y x d 6 } { X eZygote。
下面开端详细的流程剖析,终究会给出完好的交互联系图。
二、流程剖析
本部分流程剖析触及技能常识点较& 3 I I ) R | #多, 建议先对 IPC、Handler等相关常识有必定掌握。
2.1 Activity发动的建议
下面咱们就来对Activity的作业流程进行x O b K整理,到达对Activity整体流程T B _ l r的掌握。从stab l 1 C v 6rtActiv: R T ` b i O Bity办法开端,会走到startActiy _ ; ZvityForResult办法:
public void startActivityForResult(@RequiresPed Y / rrmission Intent intent, int requestCode,
@Nu~ * J | $llable Bundle options) {
if (mPn 3 @ 6 C sarent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationT| 0 / R { ,hread(), mToken, thq * K N }is,
i= e v s / tntent, requestCode p k T f r, options);
if (ar != null) {
mMainThread.sendActivityR0 / Y Q m 9 t @ _esult(
mToken, mEmbeddedID9 G X A Y, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivitJ # & ! { k g | @y = truu c 8e;
}
cancelInputsAndStaY 7 j ; ) wrtExitTransition(Z % L H M F uoptions);
} else {
...
}
}
看到里边调用了mI) ) v H HnsN & E wtrumentat~ 3 k * Zion.execStartActivity办法,其间一个参数mMainThread.getApplicationThread(),它的类型是ApplicationThread,ApplicationThread是ActivityThreab [ ) S B $d的内部类,承继IApplicationThread.Sl ( $tub,也是个Binder目标,在Activic Q j ,tyP 0 U ~作业流程中u 6 s有重要效果。而Instrumentation具有盯梢application及activity生命周期的功用,用于android 运用测试结构中代码检测。W | ! g接着看下mID : N , 8 9 { * enstrumentation.execStartActivity办法:
public ActivityResult execStar+ h M . ) $ Z 4tActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int reqf : N r l r S f {uestCode, Buq j 5 6 zndle optionsp ` s 8 q [ H) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != nulH _ )l) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
...
tr* f gy {
intent.migrateExtrc e N D I $ O haStreamToClipData();
intent.prepareToLeaveProcessC - - ^(who);
int result = ActivityTaskManager.getR t / oService()
.startActivV F lity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, t` F O C 5arget != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, i) I wntent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
这G ( 8 P {儿看到Activity的发动又交给了ActivityTaskManager.getService(),这是啥?跟进去看看:
//Activit| R [ G syTaskManager
public static IActivityTaskM} 0 E C D q [an/ $ O # } nager getServic7 v R L ! ; r ie() {
return IActi8 ? e 9 U Y % N WvityTaskManagerSingleton.get();
}
p8 W } M : Urivate static final Singleton<IActivityTaskManager> I@ 9 = : a g f G YActivityTaskManagerSingleton =! } / 5
new Singleton<IActivityTaskManager>() {
@Override
pV 5 0 ? W 4 C } Irotectz a Y C & A ! 2 ,ed IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERV{ -ICE);
return IActivityo ( M U Y G S 0 ^TaskManager.Stub.asInterface(b);
}
};
看到IBinder这个u g ; t c a H j P标志,这儿你应该理解了:这儿是获取一个跨进程的服务。获取的什么服务呢?是ActivityTaskManagerService(ATMS),它承继于IActivityTaskManager.Stub,是个Binder目标,而且是经过单例供给服务的。 AK ] @ 2 5 VTMS是用于办理Activity及其容器(使命、堆栈、显现等)的体系服务,运行在体系服务进程(system_server)之中。
值得阐明的是,ATMS是在Android10中新增的,分担了之前ActivityManagerService(AMS)的一部分功用(activity task相关)。
在Android10 之前 ,这个地方获取的是服务是AMY l W N E ] X 9S。查看Android10的AMS,你会发现startActivity办法内也是调用了ATMS的startActivity办法。所以在理解上,ATMS就隶属于AMS。
接着看,ActivityTa( i d { R 8 H %skManager.geS . ! F z 3 S ?tService().startAc: u . g Z ftivity有个返回值result,且调用了check 2 pkStartActivityResult(result,f z y intent):
public static void checkStartActivix ^ U 5 U b B ` _tyResult(int res, Object intent) {
if (!ActivityManager.! t n +isStartReO ~ t p TsultFatalErrg 3 9 J 0or(res)) {
return;
}
swit( _ ich (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case Actib - X 4 k wvityManager.START_CLASS_NOT0 , =_FOUND:
if (intent instanceof Intent && ((Intent)intT / T 5 R .ent).getComp4 r z E L Qonent() != null)
throw new ActivityNotFoundExcepW f n T ation(
"Unableq ) { to find explicit activio 3 0 M L 1 Yty clam i d 1 K V { 7ss "
+ ((Intent)intent).getComponent().toShortString()
+ "6 E ]; have you declared this activity in your AndroidMe $ Oanifest.xml?");
throw new Actia 9 & ? M $vityNotFoundException(
"No Activity found to handle " + intent);
case ActivityMao u O pnager.START_PER$ r d t xMISSION/ ^ ; [ _ y # +_DENIED:
throw new SecurityException("NotU H @ - Y 1 $ s allowed to start activity "
+ intent);
...
case ActivityManager.START_CANCELED:
throw newT u E Andrs F c AoidRuntimeExcep_ 8 { R 2tion("Activity could not be6 E Z y started for "
+ intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
这是用来查看Activity发动的结果,如果产生丧命过错,就会抛出对应的反常。看到第一个case中就抛出了 have you declared this activity in yo. E q 9 sur AndroidManifest.xml?——如果Activity没在Manifest中注册就会有这个过错。
2.2 Activity的办理—h ( L—ATMS
好了,到这儿,& L y q !Activif n 3 pty的发动就跨进程(IJ i ~PC)的搬运到体系进程供给的服务ATMS中了,接着看ATMS的startActivt F |ity:
//ActivityTaskManagerService
@Override
public final int startActi/ f , X ~ O D & Cvity(IApplicationThread caller,Y I v = j P q String callingPe b 4 | f /ackage,
Intent intent, String resolvedType, IBU Q C _ , :inder resultTo, String resultWho, int requestCode,
int startFlags, PF . 7 n N 9rofilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(cal{ R c 3 `ler, callingPackage, intent, resolvedType, resultTo,
resulJ ) ?tWho, requestCode, startFlags* - + C, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackag( a 3 N be,
Intent intent, String resolvedType, I2 x d { ^ ` FBinder resultTo, String resultWho, int requestCode,c Q = ? Z M
int startFlagL # Ns, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profiler` m & nInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
int startActivityAsUser(IApplicationThread caller, String callingP% ; R { ` [ ) b iackage,
Intent intent, String resolvedTyo y N Cpe, IBinder resultTo, String resultWho, int requestCode,
int startFlags, Profile3 L FrInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomin; , 7 w w | F e @gUser) {
enforceNoO ( ftIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCalliK Z J =ngPid(),: B g Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app st1 ; . Xacks here.
return getActivityStartControl$ E [ D =ler().obtainStar# 1 R P zter(intee 5 ~ U V Qnt, "startActivityAsUser")
.setCallN [ @ b ver(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.sek E Q Q o $ =tResultTo(resultTo)
.s h x o v @sO ^ # 9 J } etResultr [ p | T . a }Who(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilez h i # @rInfo(profilerInfo)
.se7 T ; w U Q D vtActivityOptions(bOptions)
.setMayWaite p y ((userId)
.execute();
}
跟到startActivityAsUser中,经过getActivityStartController().obtainStarter办法获取ActivityStarter实例 然后调用一系列办法,终究的execute()办法是开端发动activity:
int execute()x ? F K % {
try {
// TODO(b/64750076): Look into passing rm ~ _ F pequest directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
re: { 4 t , 1 T aturn startActivityMayWait(mRequest.caller, mRequest.callingUi: z m v f dd,
mRequest.callingPackage, mRn k y ( * 1 o #eqM j G & w n _uest.realCallingPid, A L o M z 3 p F mRequesM 1 Y o & T n A ]t.real_ 9 6 ; -CallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
m~ } . g y S - qRequest.resui R z { ltWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.gl3 ] c 0 EobalConf7 X j ^ w i Rig,
mRequest.act ? X # | V :ivityOptions, mRequest.ignoreTargetS3 } becurity,T u ; L _ ; ; g + mReA m 7 j b d :quest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRem1 Z y QoteAnimationRegistryLookup,
mRequestv l q r L r.originatingPendingIntent, mRequest.allowBackgroundActivityStartZ 8 ` I Y A G ; D);
} else {
return start` W Z wActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mN e A $Request.resolveInfo,
mRequest.voiceSessionE t $, mRequest.voiceInteractor, mRd D 3 @ / 5 k ,equest.resultTo,
mRequest.resultWho, mRequest.re ] 4 m i 3 ^equestCodeS ! R % Y * V @ k, mRequest.callingPid,
mReq$ . t _ / ? ? k Auest.callingUid, mRequest.callingPaX g n J G Qckage, mRequest.realCallingPid,
mRequ` k ` =est.realCallingUid, mReqA Q @ J W w Z R 6uest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.I A r ]componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPending; q T 0 Q S e yRemoteAnimationReg? : . D } 5 !istryLookup,
mRequest.originatingPendingIntent, mRH U T 0 d ( j cequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
分了两种状况,不过 不论st) 2 dartActivityMayWait还是startActiF ` ? ; { ? Bvity终究都是走到下面这个startActivity办法:
private int sN 5 a i 7 W StartActivity(final ActivityRecord r, ActivityRe_ $ c J Fcord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFD Z $ 2 B E ` &lags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgm ~ v ] AcA - L utivity) {
int result = START_CANCEe V N ? &LED;
final ActivityStackO K Y startedAI J ` e ! WctivityS[ # V E M 1 q ` 6tack;
try {
mSe} * V 5 & H 8rvice.mWindowManager.defew D ErSurfaceLayout(e h a = o F);
result = startActivityUn~ A t Z Z c pchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
} finally~ ) S {
final ActivitL i @ E : q ~yStack currentStack = r.getActivityStack();
startedActivityStack = currentStack != null ? currentStack : mTargetStack;
...
}
postStartActivityProcessing(r, result, startedActivityStack);
return result% _ F r @ Y C Z N;
}
里边有调用了startActivityUnchecked办法,之后调用RootActivityContainer的resumeFocusedStacksTopActivities办法。RootActivityContainer是Android10新增的类,分担了之前AN $ K 8 ] 4ctivityStackSupervisor的部分功用。接着跳转到ActivityStack的resumeTopActivityUncheckedLocked办法:
//ActivityStack
boolean resumeTopActivityUncq l . E C { eheckedLocked(Activi= o qtyRecord prev, ActivityOptions options) {
if (mInRe} m (sumeTopActivity) {
// Dont U g't even start recG + = 5 oursing.
return false;
}
boo g 0 F X R X N ,lean result = false;
try {
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, o x L % b P - ~ptions);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}f _ G
} finally {
mInResumeTopActiv7 v Q [ i 9 aity = false;
}
return result;
}
跟进resumeTopActivityInnerLocked办法:
private boolean res4 = m L ) @umeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = getDisplay().pauseBackSG G - xtacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"re_ O n ysumeTopActivityLocked: Pausing " + mResumedActN j y = $ j Zivit8 Y I 1y);
// 暂停上一个Acti9 . * % .vity
pausing |= startPausingLocked(userLeavi~ C 0 R Ing, falW d D s I G h g &se, next, false);
}
...
//这儿next.att| g S } V E D wache/ g E z P M LdToProcess(),只要发动了的ActivitR ? H 8 ) C V Ly才会返回true
if (next.attachedToProcess()) {
...
try {
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken);
...
//发动了的Activity就发送Resumec I ~ ` y R NActivityItem业务给客户端了,后边z C A n会讲到
transaction.setLifecycleStateRequ/ - V H ` a U Jest(
ResumeActivityItem.obtain(next.app.geq 5 . _ X f ` Q _tReportedProcStatex = /(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransa* r [ a c / U wctioE G i % a ;n(transaction);
....
} catch (Exception e) {
....
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
....
} else {
....
if (SHOo ` #W_APP_STARTING_PREVIEg q S * QW) {
//这儿便是 冷) V E z N发动时 呈现白屏 的原因了:取根ac) / ] t y xtivity的主题布景 展现StartingWindow
next.showStartingWindow(null , false ,false);
}
// 持续当前Activity,一般activity的正常发动 重视这儿即可
mSH d 6 2 2 u Q l XtackSupervisor.startSpecificActivityLocked(nexe E N *t, true, true);
}
returnk 3 e G ! n @ true;
}
先对上一个Activity履行pause操作,再履行当前创立操作,代码终究进入到了AA ~ _ } V J ^ctivity0 [ _StackSuperviU 5 ( k x T Gsor.startSpecificActivitd n ` N , C L 7 [yLocked办法中。这儿有个点注意下,发动w n h = % 3 uactivity前调用了next.B _ e Q $ l 2showStartingM ` ) [ [ zWindow办法来展现一个window,这便是 冷发动时 呈现白屏 的原因了。咱们持续看ActivityStackSupervisor.startSpecificActivityLocked办法:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's applicatC E 5ion already running?
final WindowP9 G [rocessController wpc =
mService.getProcessController(r.proce8 ! +ssName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;g i k C I 4 l
if (wpc != null && wpc.hasr V h &Thread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConf, 7 e d 7 , nig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting( 6 l O activity "
+ r.intf H , % ) f |ent.getComponent().flattenToShortString(), e);
}| ~ n ( / m { F u
knownToBeDead = true;
}
...
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVIg C C $ t nTY_MANAGER)) {
Trace.to 7 ! * F m N / Vra7 j h ~ T K `ceBegin(TRACE_TAG_ACTIVITYE # M v E E d_MANAGERR + ! : e o 8 8 r, "dispatchingStartProcess:"
+ r.processName);
}
// 上面的wpc != null &&aD , E Omp; wpc.haG I N 0 tsThread()不满足的话,阐明没6 6 r p 3有进程,就会取创立进程
final Message msg = P# A z e d z booledLambda.obtainMessage(
ActivityMan0 M f . !agerInternal::startProcess, mService.mAmInternal, r.processNS T % K oame,
r H J - u J k u.info.applicationInfo,* A ) E = ] , h knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnT 3 d / qd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
有个判别条件ifH q i [ m c (wpc != null && wpc.hasThread()),意思是是否发动了运用进程,内部是经过IApplicationThread是否为空来判别。这儿咱们只看已发动运用进程= f a的状况,及调用了r* P Z B 4 e @ O {ealStartActivityLocked办法,,:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andR# @ = 7esume, boolean checkConfig) throws RemoteException {
...
// Create activi^ 4 O tty launch transaction.
final ClientTransaction clientTransaction = Clg _ & _ n 4 OientTransam E Z a K ; G Yction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback9 K w e ; m(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration insu w $ F mtead of separate global
// and: m g + q : override configs.
mergedConfiguration.getGlobalConfiguration(),
mer: W G $ N hgedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.io W k N McicH 6 n , ? U le, r.persistentState, results, newIntents,
dn 1 j B @c.isNextTransitionForward(), proF & Pc.createProfilerInfoIfNeeded(),
r.assistToken));
// Set des$ ( S : + # l S Kired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleIt- R * o t M em = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecu L N W ] YycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest} - K N p a(lifecycleItem);
// Schedule traE 9 d 3 G . E : Pnsaction.
mService.getLifecycleManager().& / { & S [ ^scheduleTransaction(clientTransaction);
...
return true;
}
中间有段代码如上,经过 ClientTransaction.obtain( proc.getThr6 L . Xead(), r.appToken)获取了clientTransaction,其间参数prx 1 R w H roc.getThread()是IApplicationThj , #read,便是前面说到的ApplicationThread| k @ 4 W V `在体系进程的署理。
ClientTransaction是包括一系列的待客户端处理的业务的容器,客户端接纳后取出业务并履行。
接着看,运用clientTransaction.addCallback增加了LaunchAct. ~ ` nivityItem实例:
//都是用来发送到客户端的
private List<ClientTransactionItem> mActivityCallbacks;
public void addCaP u q !llback(Cl/ 7 + _ + 0 f Y DientTransactionItem activityCallback) {
if (mActivityCallbd g tacks == null) {
mActivityCallbacks = new Array r t KLiP . gst<>();
}
mActivityCallbacks.add(activ^ b 7 m n 3 C ; RityCallback);
}
看下LaunchActivityItem实例的获取:
/** Obtain an instance initialized with provided params. */
public static Lae ( _ K 4 n 6unchActivityItem obtain(Inte1 z C ent intentE K # b 1 L D, int ident, ActivityV 3 F sInfo info,/ @ 1 R = a h S
Configuration curCoL J % 4 # 9 knfig, ConfigC 1 W /uration overrideConfig, CompatibilityInfo compatInfo,
String referrer, IVoicU ~ A ueInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferreO s f 2 ? 3 H KrInte} f ] % 4 Ent> pendingNewIntents, boolean isForward, ProfilerIB 6 m X i | t ]nfo profilerInfo,
IBinder assistToken) {
LaunchAcJ g u K ) L a ) `tiv! n C ` 4 u HityItem instance = ObjectPool.obtainE r H E % e(LaunchActivityItem.class);
if (instance == null) {
instance = new LaunchActivityItem();
}
setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
voiceInteractor, procState, state,b u b Q persistentState, pendingResults,
pendingNeT m ~ ! # + z d ^wIntents, isForward, profilerInfo, assistToken);
return i1 o m R /nstance;
}
new了一. * ) ~ $ : –个LaunchActivityItem然后设置各| ? G R .种值。咱们从名字就能看出,它便是用来发动activity的。o W w它是怎样发挥效果的呢?接着看:
回到realStartActivityLocked办法,接着调用了mService.getLifecycleManager().scheduleTransaction(clientTransaction),mService是ActivityTaskManagerService,getLifecT * N nycleManager()办法获取的是ClientLifecycleManager实例,它的scheduleTransaction办法如下:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transact~ 9 W p } : m Lion.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transac M /ction.recycle();
}
}
便是调用Clientt J % Q eTra* Q / D ; f :nsaction的schedule办法,那就看看:
public void schedule() throws RemoteException {
mClient.scheduleTransaction(thiS 7 us);
}
很简略,便是调用IApplicationTh P ,hread的scheduleTranr q ] 3saction办法。由于IApplicationThread是ApplicationThread! $ { 4 m B在体系进程的署理,所以真实履行的地方便是 客户端的ApplicationThread中了。也便是说,Acth i H * 6ivity发动的操作又跨进程的还给了客户端。
好了,到这儿咱们稍稍整理下:发动Activity的操作从客户端 跨进程 搬运到 ATMS,ATMS经过ActivityStarter、ActivityStack、ActivityStackSupervisor 对 Activity使命、activity栈、Activity记录 办理后,又用过跨进程把正在发动进程又搬运到了客户端。
2.3 线程切换及音讯处理——mH
接着上面的剖析,咱们找到ApplicationThrv p D {ead的scheduleTransaction办法:
@Override
public vM v $ c + o B ?oid scheduleTransaction(Client ( $ n R m m _ 9Transaction transactioC # X v O ~ L gn) throws RemoteException {
ActivityThread.th3 6 O I 3 A L [is.scheduleTransaction(transaction);
}
那就再看ActivityThread的scheduleTransaction办法,实践在其父类ClientTrw O L k [ansactionHanh C m Z `dler中:
voM Y h % 8 Eid scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(Ac? D Q H e P X 8tivityThre_ n Q m tad.H.EXECUTE_TRANSACTION, transaction);
}
运用sendMessage发送音讯,参数是Activitu & – 1 F g iyThread.H.EXECUTE_TRANSACTIO8 ? I L QN和transaction,接着看:
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void seo 5 + x j a EndMessage1 5 * . b F ` y 0(int wh? L H Z t ; 7 [ ~at, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) {
Slog.v(TAG,
"SCHEDULE " + what + " " + mH.codeToSti w . S y 2 %ring(what) + ": " + arg1 + " / " + obj);
}
Message msg = Message.obtain();
msg.y V e V W . b ]what = what;
msg.obj = obj;
msg.arg1Y L ; s 7 = V : = arg1;
msg.arg2 = arg2;
if (async) {
msg.se8 B Z D _ Q S utAsynchronous(true);
}
mH.sendMessage(msgK 7 E 2 g E);
}
终究调用了mH.sendMessage(msg),mH是个啥K / K K N n?咱们看看:
//ActivityThread
final H mH = new H()[ u z J J [;
class H extends Handler {
public static final int BIND_APPLICAT% 0 u %ION = 110;
@UnsupportedAppUsage
puf b 2 N _ { sblic static final int EXIT_APPLICATION = 111;
@UnsupportedAppUsage
public static finp j E z l g @ = )al int RECEIVER = 113;
@UnsupportedAppUsage
public static final int CREATE_SERVICE = 11w 6 * n p4;
@UnsupportedAppUsage
public static final int SERVICE_ARGS = 115;
...
publiD M 8 f i I Cc static final int EXECUTE_TRANSACTION = 159;
public static fl s a g / v 5inal int RELAUNCH_ACTIVITY =i l M : } # ) 160;
.A c ] D..
public voiM y 6 g Od handleMessage(Message msg) {
if (DEBUG_MESS+ N l %AGES) Slog.v(TAG, ">>> handling:N 9 G E " + codeToString(msg.wha5 H 9 Z ^t));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBeginc q v(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindD0 Y pata)msg.obj;
handleBindd q JApplication(da@ Z & +ta);
Trace.! N # xtraceEnd(Trace.T1 * ^ +RACE_TAGO F W 7 e_ACTIVITY_MANAGER);
break;
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;
caseb P S a RECEIVER:
Trace.traceBegin(Trace.TRACE_TAG_ACT_ ) # y + . =IVITY_MANAGER, "broadcastReceiveComp");
handleReceiver((ReceO B MiverData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTa c a Z 6 9 F yIVITY_MANAGER);
break;
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGERw y ) ( 1, ("serg t ^viceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trac. 3 W * Xe.TRACE_TAQ m q / +G_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Tracen @ N P = 0 | F r.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Tracef 0 5 w w 6.traceEnd(TraceX , m t.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTrJ ` D x u =ansaction) msg.obj;
mTransactionExecutor.execute(transactiont O v w x ();
if (isSystem()) {
// Client transactions inside systK J 4em process are recycled on the clien[ K e r ) 0 G - tt siW N d Tde
// instead of ClientLifecycleManager to ad 4 uvoid being cleared before this
// message is handled.
transact@ K * & Cion.recycle();
}
break;
case RELA^ J _ {UNCH_ACTIVITY:
handleRelaunchActivityLocally((IBinder) msg.obj);
b$ * A X / $ /reak;
...
}
Object obj = msg.obj;
if (obj i5 h Q W F Knstanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
if (DEBB b C ( d d I 0 CUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.wZ ? d 2 W hat)Q 1 s o / r e);
}
}
mH是在创立ActivityThread实例时赋值的,是自定义Handler子类H的实例,也便是在Activitf , ( X = wyThread的main办法中,而且初始化是现已主线程现已B A d k /有[ m =了mainLooper,所以,运用这个mH来l l x 5 9 w YsendMessag[ : Xe就把音讯发送到了主线程。
那么是从哪个线程发送的呢D ( d H k _ W r e?那就要看看ApplicationThread的scheduleTransaction办法是履行在哪个~ B ; i ] _线程了。根据IPC常识,咱们知道,服务器的Binder办法运行在Binder的线程池中,也便是说体系进行跨进程调用2 j B n = j TApplicationThread的scheduleTransaction便是履行在& ! j ) v h V { Binder的线程池中的了。
到这儿,音讯就在主线程处理了,那么是怎样处理Activity的发动的呢?接着看。咱们找到ActivityThreK w & ) R –ad.H.EXECUTE_TRANSACTION这个音讯的处理,就在handleMessage办法的倒数第三个case(就在上面代码):取出ClientTransaction实例,调用TransactionExecutor的execute办法,那就看看:
pu A [ ( c - X 4blic void execute(ClientTransactz o t ! 5 U Mion transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction/ k n * * ` ,.getActivityToken();
...
exey ~ , m n K PcuteCallbacks(transaction);
executeLifecycleState(transactN H G r f Wion);
...
}
持续跟进executeCallbacks办法:
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallZ M T ! 9 W z a lbacks();
if (callba+ 3 P l 6 % d _cks == null || callbacks.isEmpty()) {
// No callbacks to executeW N O, return early.
return;
}
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transacA H C x P a dtion) + "Reso@ ] 4 a ^lving call+ q b o abacks in transaction");
final IBinder token = transacx C = l : 6 J 7 ~tion.getActivityToken();
ActivityClientRecord r = mTran% R LsactionHandler.getActivityClient(token);
// In case when post-executiq _ * i n & qon state of the last callbacD I h rk mC g y xatch+ o res the final state requested
// for the activity in this transaction, we won't do the last transition here and do it when
// moving to final state instead (because it may contain additional parameters from server).
fi: V { 5 ~ hnal ActivityLifecycleItem finalSD | C f G btateRequest = trm Z % 7 N W g ! ansaction.G ` PgetLifecycleStateRequest();
final int finalState = finalStateRequest != null ? fiT m p Y DnalStateRequest.getTargetState()
: UNDEFINED;
// Index of the last callback that requests some post-execution state.
final intB G { d G ^ D lastCallbackRequesti. B 9 ingState = lastCallbackRequestingState(transaction);
final int size = callbacks.size() B );
for (` , / J 9int i = 0; i <n v M G { c size; ++i) {
final ClientTransactionItem item =W + P { y Q callbacks.get(i);
...
item.execute(mTransactionHandler, token, mPendingAction! 9 c 7 Gs);
item.postExecute(mTransactionHandler, token, mPendingActions);
...
}
}
遍历callbacks,调用Cliet % p 1ntTransactionItem的execute办法,而咱们这儿要重视的是ClientTransactionItem的+ ? d # b K 9子类LaunchActiviX y MtyItem,看下它的exe8 k & n : ecute办法:
public void ex_ o +ecute(ClientTransa/ ) L 4ctionHandler cliz q h g |ent, IBinder token,
PendingTrans~ 8 s G ! ` N CactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTW l . wIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIde _ i bn( K x ! W Z yt, mInfo,
mOverrideCo` w p 3 z J z _ nfig, mCompatInfo, mReferrer, mVoicB O ; Q u : C c beInteractot l [ W Hr, mState, mPersise p DtentState,
mPendingResults, mh N I M I ~ t X aPendingNewIntents, mIsForward,} 3 d | J c u $
mProfilerInfo, client, mAssistToken);
client.handleLaunchActivityj y } 5 s 0 ; C I(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
里边调用了client.handl_ m $ $ 0 ^ , QeLaunchActivity办法,clientI Z M是ClientTransactionHandler的实例,是在TransactionExecutor构造办法传入的,Trans; e 8 c @ bactionExecutor创立是在ActivityThread中:
/r z ~ y t ~ d 0 H/ActivityT^ ( * O L T q ;hread
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(= l Q tthis);
所以,client.handleLaunchActivity办法便是ActivityE ] y ) _ l @Thread的handleLaunchActivity办法。
好了,到这儿 ApplicationThread把发动Activity的操作,经过mH切到了主线程,走到了ActivityThread的handleLa~ r U x J ` ) KunchActivity办法。
2.4 Activity发动中心完结——初始化及生命周期
那就接着看:
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, cus# b e 1tomIntd t - { hent);
...
return a;
}
持续跟performLauncf – + 0 t l s &hActivity办法,这儿便是activity 发动的中心完] L t | N 3 w w结了:
/** activity 发动的中心完结p . c F ; {. */
pri^ ^ g q .vate Activity performLaunchActivity(ActivityClientRecord r, IP J Nntent customIntent) {
//1、从ActivityClientRecord获取待发动的Activi} 1ty的J N 9组件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_COD4 B 1 m x E ` s $Eg q % });
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mIA g h hnitialApplication.getPackageManager());
r.intent.setCoq E H % B M $mponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentS v % e ) [ 7 ` cName(r.activN ; 1 *ityInfo.packageName,
r.activiti 0 k N xyInfo.targetActivity);
}
//创立ContextImpl目标
ContextImpl appContext = createBaseContextForActivity| d l X(r);
Activity activity = null;
try {
//2、创立activity实例
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassN: } 6 # 0 g Aame(), r_ ) N A F ^ ` S.intent);
StrictMode.iT D - @ i C $ rncu O J e - G x %rementExpectedActivityCount(activity.getClasY f x I G u fs());
r.intent.setEx/ / ; % m t % 4trasClasa | ; h q `sLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (J d % H i lException e) {
..
}
try {
//3、创立Application目标(如果没有的话)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != nu: k t T h j } @ll) {
CharSeqo ? p H O r M Huence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config, 7 } t Y O S w J = new Configuration(mCo{ W lmpatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow* _ & =5 M $ E J ( G 4 2 nul @ A R Ql;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
//4、attach办法为activity相关上下文环境
activity.attach(appCok } P ) . m ntext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.las$ R B 3 X &tNonConfigurationInstances, config,
r.reW H R U ( L m . yferrer, r.voiceInteractor, window, r.configCallback,
r.assi{ P x 6 [ _stToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBl7 $ O M Z + R ^ockForNetworkAccess();
activity.mStartedActivity = false;c E n % [ n 4 J
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setThem) y y /e(theme);
}
activity.mCalled = false;
//5、调用生命周期onCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(act] D 5 a p P _ivity, r.state, r.persistentState);
} else {
mInstrumentaM R gtion.callActivityOnCrv , x 4eate(activity, r.state);
}
iy T - 9 = X xf (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShorQ p 1 ^ _ JtString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
r.s? ! = i Y [etState(ON_CREATE);
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
}
...
return activity;
}
performLaunchActivity首9 q 7 9 d g T v T要完结以下作业9 6 = n n:
- 从ActivityClientRecord获取待发动的Activity的组件信息
- 经过mInstrumentation.n? P G h . 8ewActivity办法运用类加载器创立activity实例
- 经过LoadedApk的makeApplication办法创立Application目标,内部也是经过mInstrumentation运用类加载器,创立后就调用了instrumR ! ^ * ; | c B bentation.callApplicationOnCreaT t 5te办法,也[ S V便是ApplicatiN ( . ) O – , 9on的onCreate办法。
- 创立ContextImpl目标并经过activity.attachM + / =办法对重要数据初始化,相关了Context的详细完结ContextImpl,attach办法内部还完结了window创立,这样Window接纳到外部事情后就能传递给L y D 9 } C . uActivity了。
- 调用Activity的onCreate办法,是经过 mInstrumentation.callActivityOnCreatp } J = N Q ue办法完结。
到这儿Activity的onCreate办法履行完,那么ond p C ) JStart、onRes3 y 4 g z Tum– ? L h = me呢?
上面看到LaunchActivityItem,是用来发动Activity的,7 U . # 0也便是走到A% ! $ L % 7 Jctivitx + ty的onCreate,那么是不是有 “XXXActivityItem”呢? 有的:
- LaunchActivityItem 长途App端的onCreate生命周期业务
- ResumeActivityItem 长途App端的onResume生命周期业务
- PauseActivityItem 长途App端的onPause生p P e F ( S G f命周期业务
- StopAY o 8 5 ;ctivityItem 长途App端的onStop生命周期业务
- DestroyActivityItem 长途App端onDestroy生命周期业务
别的整理进程中触及的几个类:
- ClientTransaction 客户端业务控制者
- ClientLifecycleManager 客户端的生命周期业务控制@ B e者
- TransactionExecutor 长途通讯业务履行者
那么咱们再来看看f [ [ G LResumeActivityItem吧。
咱们再来从头看看在ActivityStackSupervisor的rer } 9 y : = calStartActivityLocked办法:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andRe5 C h d k * T $ &sume, boolean checkConfig) throws RemotA q g q c Q ) |eException {
...
// Create activity launc, f $ H Th transaction.
final ClientTransaction clientTransaction = ClientTransactiM r j _ G # ?on.obtain(
proc.getThread(), rd . U - U ) } Z.appToken);
final Displa2 l 9 m ( 9yContent dc = r.getDisP ? s `pl+ a H s g ` m H 0ay().mDisp( ) U h : * glayCon? 8 g ! t j 0 I Btent;
clientTransactio@ , I ] b j ) 1 {n.addCallback(LaunchActivityItemB h ) / J / {.obtain(new Intent(r.intent),
Sy6 % _ ( } kstem.identityHashCode(r), r.& a ] Minfo,
mergedConfigurat! U S O V m @ )ion.getGloba5 ] # U _ H e e HlConfi{ N A E y + w O pguration(),
mergedConfiguration.getOverrideCon- X P H +figuration(), r.compatV I q,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcSr % (tate(),
r.icicle, r.persistentState, results, newInD d y = _tents,
dc.isNextTransitionF) d Dorward(), proc.O % i ( H YcreateProfilerInfoIfNeede? Q 4 9 $ q w | yd(),
r.assistToken));
// Set desired final state.
final ActivityLifecycleItem li~ R 3 _ ? Rfe C + ) ! R U 0 FcycleItem;
//这儿ResumeActi_ g : 2 3 ` DvityItem
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNe9 m H R o m F FxtTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateT a M Y 6 ? fRequest(lifecycleItem);
// Schedule transaction.
m+ q O $ H OService.getLD 3 / OifecycleManager().schedu2 D i 5 d bleTransO L t [ D + ? * 2action(clientTransaction)z f;
...
return true;
}
前面只说了经过cli! p T ` JentTransaction.addCallback增加LaunchActivityItem实例,在注意下面接着调用了clientTk k T v 8 5 #ransaction. C a d z jsetLifecycleStateRequest(lifecy6 z Z I C b J [ TcleItem)Q X Y 8 ?办法,lifecycleItem是ResumeActivityItem或PauseActivityItem实例,T + k x t 2 J这儿咱们重视ResumeActivityItem,先看下setLifecycleStateRequest办法:
/**
* FinalT 6 . b $ N c 5 lifecycle state in which the client activity should be after the transaction is
* executed.
*/
private ActivityLifecycleIteme - J / s I mLifecycleStateRequest;
public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
mLO P X U ; _ b `ifecycleStateRequest = stateRequest;
}
mLifecycleStateRequest表明履行transaction后的终究的生命周期状况。
持续看处理ActivityT@ , x D } L A 9hread.H.J t + 1 2EXECUTE_TRANSACTION这个音讯的处Q 7 o理,即TransactionExecutor的execute办法:
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TA_ c J . 2 } uG` Q 3 ? o, tId(transaction) + 2 b y S ["Start resolving transactionn 9 Q . 2");
final IBinder token = transaction.getActivityToken();
...
execu4 P F 3 ~ + ) W steCa9 : 2 e L Rllb_ = t h Kacks(transaction);
executeLifecycleState(transactir q h H X A * won);
...
}
前面咱们重视的是executeCallbacks办法,现在看看executeLifecycleState办法:
/** Transition to thJ | D O w s @ Qe final state if requested by the transactp W u R b _ w $ ?ion. */
private voa T pid executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = tran$ ~ k ? I A Y 7saction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
final IBinder token = transac( u H T l g 1tion.getActivityK B O a ` l w T nToken();
final ActiviD t q d B @ `tyClientRecord r = mTransactionHandler.getActivityClient(token);
...
/D L { // Execute the final transition with proper parameters.
lifecycleItem.execute(P T Q U N 7 , nmTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingR s S I N ~Actions);
}
这儿取出了ActivityLifecycleItem而且调用了它的executZ W D V 3e办法,实践便是ResumeActivityItem的办法:
@Ove; R 0 w Vrride
public void execute(ClX B I ; k #ientTransactionHandler client, IBinder token,
PendingTraN { | % - = c &nsactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivij K T 1 t o 1 .ty(token, tr` ) 0 o = $ s ! .ue /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TR_ U G [ + U B U WACE_TAG_ACTIVITY_MANAGER);
}
经过上面剖析实践是走到ActivityThread的handleResume, 2 q t nActivitZ h z r & | : w Ky办法:
@Override
public void handleResumeActivity2 | F K c(IBinder token, boolean finalStat} M U LeRequest, boolean isForward,
String reason) {
...
// performResumeActivity内部会走onStart、oJ 8 = ( pnResume
final AcA F etivityCq 6 P p A t qlientRecox u _ Mrd r = performResumeActivity(tox o 6 M oken, finalStateRequest, reason);
if (r == nullQ z Q #) {
// W0 X c 6 :e didn't actually resume the acti& c 7 Q B 2 | svip u ! O A q $ n bty, so skipping anw l D 6 e % ? oy follow-up actions.
return;
}
...
if (r.window == null && !a.mFin/ ? r Z lished && willBeVisible) {
r.window = r.activity.getWindow(3 f t);C ^ ( T , Z W
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViX * - weE M S = n A WwManager wm = a.getWindowManage% ] g * 1 qr();
WindowManager.LayoutParams l = r.window.getAttributR 2 6 | 0 T `es();
a.mDeck r 6 . B ( Dor = decoW ( C (r;
l.type =z P a WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImD $ R d s k 8pl();
if (impl != nullx o % | e k [) {
impl.notifyChildRebuilt();
}
}
...
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForN& E v 0 f ] O Qow) {
if (r.newConfig != null) {
performConfa ] 9 Piz S H 1 p HgurationChangedForActivity(r, r.newConfig);
if (DEBUG_CONFIGURATION) {
Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
+ r.activity.mCurrentConfig);
}
r.newConfig = null;
}
if (localLOGV) Slog.v(3 c 2 U + z , BTAG, "Resuming " + r + " with isForward=" + isForward);
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowMana9 j & I Z = ]ger.LayoutParams.SOFTL ^ x F O 5_INPUT_IS_FORWARD_NAVIGATION))
| fov D 1 u a ! : A xrwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.g, V 1 W W K $ xetWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(dN 6 N & D 0 Eecor, l);
}
}
r.activity.mVisibleFromServer = truN + U a R te;
mNumVb H r PisibleActivities++J 8 % { % N 0 F;
if (r.activity.mVisibleFromClient) {
//增加window、设置可见
r.activity.makeVisible();
}: / I C 9 q / m
}
r.nex| z vtIdle = mNewActivities;
mNewActiviv 0 j L =tiesC e i I q = r;
if (localLOGV) Slog.v(TAG, "Scheduling idle ht H y F + { d . -andler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
handleX ? 7 Y U R Q t ^ResuP 6 u | ( J )meAf B V u $ ectivity首要做了以下作业:
- 调用生命周期:经过performResumeActivity办法,内部调用生命周期onStart、onResume办法
- 设置视图可见:经过activity.makeVisible办法,增加} % (window、设置可见。(所以视I . 9 ) B – o图的真实可见是在onResume办法之后)
先来看第一点,生命周期的调用。即performResuv L A A S 0 TmeActivity办法:
public Activi[ o m W (tyClientRecord performResumeAcW C V 9 W G J vtivity(IBinder token, bS Z V p h R D | Roolean finalStateRequest,
StrI i O y D +ing reasoX J Pn) {
final ActivityClientRecord r = mActiviti{ R ^ &es.get(token);
...
try {
...
r.activity.performResume(r.startsNoR o V . x ktResumed, reason);
...
}
...
return r;
}
调用了activity.performResc / j 8 ;ume办法:
final void perform} 1 U / h a X =Resume(boolean f) f G xollC 2 j M GowedByPause, String reason) {
dispatchActivityPreResumed();
//内部会_ U C K 6 U t 3走onStart
performRev | ` Wstart(true /* sW d Z L n ^ d ? ,tart */, reason);
...
// 走onResum] k x f } h 0 l 7e
mInstrW b t d Wub } { w I (menF 8 : c Ctation.callActivityOnResume(this);
...
//这儿是走fragment的onResume
mFragments.dispatchResume();
mFragments.execPendingActions();
...
}
先调用了performRestart(),performRestart()又会调用performStart(),performStart()内部调用了mInstrumentation.callActivityD T } i zOnStart(this),也便是**Activity的onStart()**办法了。
然后是mInstrumentation.callActivityOnResume,也便是**ActivitV E @ Iy的onResume()**办法了。到这儿发动后的生命周期走完了。
再看第二点,设置视图可见。即activity.makeVisible()办法:
//Activity
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow()g S o H o q s.getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
这儿把actia h l Bvity的尖端布局mH / x +Decor经过wK o 6 Z s B zindowManager.addView()Q a W , R M ! W n办^ / {法,把视图增加到window,并设置mDecor可见。到这儿视图是真实可见了。值得注意的是,视图的真实可见– k H Y是在^ 2 h D soG C z h z { t w :nResume办法之后的。
好了,到这儿便是真实创立完结而且可见了。
整( T *理成联系图如下:
触及的类整理如下:
类名 | 效果 |
---|---|
ActivityThread | 运用的入口类,体系经过调用main函数,敞开音讯循环队列。ActivityThread所M _ – Y U Z u ^在线程被称为运用的主线程(UI线程( – 2 A) |
ApplicationThread | 是ActivityThread的内部类,承继IApplicationThread.Stub,是一个IBinder,是ActiivtyThread和AMS通讯的桥梁,AMS则经过署理调用此App进程的本地办法,运行在Binder线程池 |
H | 承继Handler,在ActivityThread中初始化,即主线程Handler,用于主线程一切音讯的处理。本片中首要用于把音讯从Binn / W ] $ der线程池切换到主线程 |
Intrumeb q | lntation | 具有盯梢a! ) )pplication及activity生命周期的功用,用于监控a1 P – m ) . [ o Mpp和体系的交互 |
ActivityManagerService | Android中最中心的服务之一,担任体系中四大组件的发动、切换、调度及运用进程的` * U P z w b办理和调度等作业,其职责与操作体系中的进程办理和调度模块相相似,因而它在Android中非常重要,它本身也是一个Binder的完结类。 |
ActivityTaskManagerService | 办理activity及其容器(task, stacks, d+ o G . 8 9 misplays)的体系服务(Android10中新增,分担了AMS的部分职责) |
ActivityStarter | 用于解释怎样发动活动。该类搜集一切逻辑,用于确定Intent和flag应怎样转换为活动以及相关的使命和堆栈 |
ActivityStack | 用E h @ p +来办理体系一切! } c r = V 1 =的Activity,内部保护了Activity的一切状况和A~ & y Rctivity相关的列表等数据 |
ActivityStackSupervisor | 担任一切Activity栈的办理。AMS的stack办理首要有三个类,ActivityStackSupervisor,Activ : 2 : Z ]vityStack和TaskRecord |
ClientLifecycle, i J 4 F 2Manager | 客户端生命周期履行恳求办理 |
CL n j K C C L * }lientTransaction | 是包括一系列的 待客户端处理的业务 的容器,客户端接纳后取出业务并履行 |
LaunchActivityItem、ResumeActivityItem | 承继CB Y Q % VlientTransactionItem,客户端要履行的业务信息,发动activity |
以上便是一个 一般Activity 发动的完好流程。
为啥我说 “一般Activity” 呢?由于你会发现,整个流程~ h c s l D是从startActivity这个办法9 B Z j U & P开端的,是咱们在m m b一个Activity里边发动另一个Activity的状况。那么第一个Activity,即 根Activity 是怎样发动的呢?
别的还注意到,在ActivityStackSupervisorF Z u @ S的startSpe* 9 Z h Z %cificActivityLod 2 i L C 1 .cked办法中,上面剖析有说到,有个判别条件if (wpc != null &&s s | | B l J D wpc.hasThread()),意思是 是否发动了f g .运用进程,而咱们只剖析了已发动运用进程的状况。那么未发动运用进程的状况便是根K L Y t W X T *Activity的发动了。下面就来了解根Activity的发动,也能够理解为运用程序的发动进程。
三、根Activity的发动—运用进程发动
咱们知道,想要发动一个运用程序(App),需求点击手机桌面的运用图标。Android体系的桌面叫做Launcher,有以下效果:
- 作为Android体系的发动器,用于R b % w A j ] v发动运用程序。
- 作为Android体系的桌面,用于显现和办理运用程序的快捷图标和其他桌面组件。
Lau d i c G = E gncher本身也是一个运用程序,o 0 = ?它在发动进程中会恳求Packagej 5 m oManageService(体系的包办理服务)返回体系中现已安Z ( G (装的app的信息,并将其用快捷图标展现在桌面屏幕上,用户能够点击图标发动app。例如华为s [ ? W手机的Launcher便是 “华为桌面” 这个体系apo : % F wp。
3.1 运用进程的创立
当点击app5 J ( ) g # G @图标后,0 g 5 t 8 0 E WLauncher会在桌面acti8 1 ] c x Z pvity(此activity就叫Launcher)内调用startActivitySafely办法,startActivitySafely办法会调用startActivity办法。接下来的部分就和上面剖析的 Activity发动的建议 进程一致了,即经过IPC走到了ATMS,直到ActivityStackSupervisor的7 q : 7 J n 6 . :startSpecificActw 8 j ( 4 kivityLocked办法中对运用进程是否存在的判别。咱们再次瞅瞅:
void staq e 8 N BrtSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's applicationG c V b = q M 6 already running?
final WindowProcessC} . ( Q 6 xontroller wpc =
mService.getProcessControll9 M 2 z &er(r.pr# G Z HocessName, r.info.applicationInfo.uid);
boolean kns A R $ownToBeDead = false;
if (wpc != null &Y s ^ M 4 c }& wph 0 / { m m cc.p ? i Q NhasThread()) {
tryZ 6 8 K 9 {
//有运用进程就发动activity
realSZ 4 N P g d % }tartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenTR C ? hoShort6 p g (Sc 5 # Z E Y %tring(), e);
}
knownToBeDead = true;
}
..h , } ? N.
try {
if (Trace.isTagEnabled(TRACE_TAG{ L ` )_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispats S E * } y V R TchingStartProcess:"
+ r.processName);
}
// Post message to start pro5 5 p 6 ; Bcess to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
// 上面的wpc != null &&~ ! ^ A 5 Pamp; wpc.hasThread()不_ X Z j v满足的话,阐明没有进程- W S d,就会去创立进程
final Message msg = PooledLO | q j 6 Lambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.i ) Pinfo.applicati~ 6 N $ - A B U nonInfo, knownToB$ M i N 7 M l e =eDead, v { y J h k N"activity", r.intent.getComponent());
mService.mH.seB q 1 i 2 6ndMessS g Z T p qage(msg);
} final} 8 N i l I ~ Fly {
Trace.traceEnd(TRACEP 6 M ~ :_TAG_ACTIVITY_MANAGER);
}
}
逻9 5 B辑很明晰:有运用进程就发动activity(一般ac: t G J – r ztivity),没有就去创立进程(然后再发动根activity)。
运用进程存在的判别条件是:wpc != null &R N & :amp;& wpc.hasThrW v 6 4 r @ead(),看下WindowProcessController的hasThread办法:o { u 2 z :
// The actual proc... may be null only if 'persistent' is true (in whic s n ; Y D i W 6ch case we ar4 ] s [ F R u G 2e in the
// process of launching the` H $ app)
private IApplicationThread mThread;/ D ` 6 c - Q {
boolean hasThread() {
return mThread != null;
}
前面已有阐明,IApplicatS _ M s VionThread是ApplicationThread在客户端(app)在服务端(体系进程)Z g 0的署理,这儿判别 IApplicationTx l ! 0 ] q M hread不为空 就代表k c | { t ; 7 0进程已存在,为啥这么判别呢?这儿先猜想,进程创立后,必定会有给IApplicationThread赋值的操作,这样就契合这个逻辑了。咱们持续看,瞅瞅进程是怎样创立的,以及创立后是否有给IApplicationThread赋值的操作。
运用ActivityTaskManagerService的mH(承继handler)发送了一个音讯,音讯中第一个参数是ActivityManagerInternal::startProcess,ActivityManagerInterna/ m yl的完结是AMS的内部类LocalService,LocalService的startPr0 e A B & x T U _ocess办法调用了AMS的startProcessLocked办法,那么咱们就看看AMS 的startProcessLocked办法,这儿应该便是创立进程了:
fi! ? f Y Gnal ProcessRecordp 9 _ w p 9 R s] F !tartProcessLocked(String processName,
ApplicationInfo info, boolean knoV 2 4 Z ]wnToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBootin) _ _g,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProceM ! / O HssLocked(p( ( m 4rocessName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI ov. I f S + q Verride */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandH 6 ^ Z f 9 6ler */);
}
这儿调用了ProcessList.startProcessLocked办法,内部又多次调用了startProcessLocked不同的重载办法,终究走到startProcess办法:
private Process.ProcessStartResult s. g t PtartProcessT m * q(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtime? X & I Z 5 t Flags, int mountExternal,2 @ & ] Y
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
...
startResult = Process.start(entryPoint,
apX ~ j C Dpi # p 0 J J j $ $.processK 4 = 4 u u uName, uid, uid, gids, runtimeFlags, mountExternal,
app.inf% w ~ 7 bo.targetSdkVersion, seInfo, requiredAbi, instructionSet,
a| t _pp.info.dataDir, invokeWith,l . s app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkSlow(startTime, "startProcess: returned from zygote!");4 0 S M
return startResult;
} finally {
Trace.trv Y 8 4 HaceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
调用了ProF K A E S C e Xcess.start办法,跟进看下:
public static ProcessStartResult st; 7 c # y (art(@NonNull final String proce: z c N EssClass,
@Nullable final String niceName,
int uid, int gid, @Nullable( s Q X & P int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@NullableU w J String seInfo,
@N4 R r Q i onNull String a0 J gbi,
@Nullable String instructionSet,
@Nullablh 6 ) m % % n ^ ue Stris | x & O Bng appDataDir,Y N C # [
@Nu- g & I _ 8 7llable String invokeWith,
@Nullable String packageName,
@Nul4 6 0 ^lable String[]F x y @ % { w zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSC l ; 4 a ( ket, apx [ #pData# ` ( ^ J ~ FDir, invokeWith, packageName,
/*useUsapPool=*/ trW x _ zue, zygoteArgs);
}
ZYGO o Q %OTE_PL @ NROCESS是用于坚持[ ^ / Z p 3与Zygote进程的通讯状况,发送socket恳求与Zygote进程通讯。Zygote进程是进程孵化器,用于创立进程s X O [ { j 8 `。ZYGOTE_PROCB c 9ESS的starm h Tt就不再跟进j v – B (去了,关于这块常识能够参阅《Android进$ x X阶解密》第二章、第三章。咱们只需求知道其内部:
- Zygote经过fork创立了一个进程
- 在新建的进程中创立Binder线程池(此进程就支持了Binder IPC)
- 终究是经过反射获取到了ActivityThread类并履行了main办法
3.2X P ! W H ] 根Activity的发动
在之前文章 Handler:Android音j = ] +讯机制–《Android开发艺术探索》阅读笔记——第十章 中介绍主线程的音讯机制时就介绍过AcX e a 7 3 b otivityThread的main办法,首要便是敞开了主线程的音讯循环。
final H mH = new H();
pud ? z | r ~ w 9blic static void main(String[] args) {
...
//1、预备主线程的Looper
Looper.prepareMainLooper();
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[! [ c - ^i] != null &F A , J Y& args[iP a R f o U U [ [].startsx , ? KWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
/_ # p , H Z 7 G/这儿实例化ActivityThread,也就实例化了上面的mH,便是handler。
ActivityThread threadq o E = new ActivityThread();
thp f ` 1 J +read.attach(false, st3 / b r z @artSeq);
//获取handler
if (sMainThreV T v ~ B S % LadHandler == null) {
sMainThreadHax j ^ | { $ |ndler = threadV r F ) X = H.getHandler();
}
...
//主线程looper敞开
Looper.loop();
//由于主线程的Looper是不能退出的,退出就无法接受事情了。一旦意G y E 5 @ e _ * C外退出,会抛出反常
throw new RuntimeException("Main tD * ~ 6 chread loop unexpectedly exited");
}
在这理,咱们重视 这两这行代码:
Activ] p | & z O 5 r NityThread thread = new ActivityThread();
threM 7 n K yad.attach(false, startSeq);
创立ActivityThread实^ o F 6 0 c ) U H例,同时会创立N K M G n &App9 / FlicationThread] a 0 O V实例,ApplicationThread实例是Act+ 2 { ivityThread实例的属性。然后调用了attach办法:
private void attach(boo c m , ) , SleW % S b [ 4 E ^ van system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;! R ( i 1 = 4 x x
if (!system) {
android.ddm.D) { 4dmHandlC f |eAppName.setAppName(` E 3 r s"<pre-initialized&9 } . _gt;"i P &,
UserHandle.myUs~ ` $erId1 ^ F + h());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
//+ 2 $把At r N i y k k w jpplicationThread实例相关到At F X A * L zMS中
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
...
}
前面说到过这儿mgr便是AN + )MS在7 Z . d L R P A客户端的署理,所以mgr的attachApplication办法,便是IPC的走到AMS的attachApplication办法了:
public finr l r u : ] ^al void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (thE $ Y _ L ! y hisi m 0 A * !) {
int callingPid = Binder.getY Z & ]CallingPid();
final int callingU{ D ! w Z pid = Binder.getCalm D C 5 3lingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, cal3 ` glingPid, callinL y @ . E S P *gUid, startSeq);
Binder.re` ~ zstoreCallingIdentity2 / # e(origId);
}
}
attachApplicationLocked办法很长,这儿保留重要的几点:
private final boolean attachAppa L # xlicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
//1、IPC操作,创立绑定Application
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnaa P Ubled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.iK - 6 V ( K ! ( rsPersisten a j 7 @ J {t(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.K % - # | Wcompat, getCommonSerO } NvicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
...
// 2、赋值 q 7 *IApplicationThread
app.makeActive(thread, mProcessStats);
...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//3、经过ATMS发动 根activity
dI b 9 ? { xidSomething = mAtmInt9 U Z c ;ernal.attachApplication(app.geL } & QtWindowP% + - _ %rocessController());
} catch (Exceptio. d m ] rn e) {
Slog.wtf(TAG, "Exception thrown launchf p a ^ 8iG b ;ng ack n # 9tivities in " + app, e);
badApp = t; d . ] g H & V Brue;
}
}
...
}
AMS的attachApplicationLocked办法首要三件事:
- 调用IApplicationThread的bindApplication办法,IPC操作I m ! I 1,创立绑定Application;
- 经过makeAW j d 8ctive办法赋值IApplicationThread,即验证了上面的猜想(创立进程: O O ( { A q z后赋] @ L c ~值);
- 经过ATMS发动 根activity
先看makeActive办法:
public void m/ W u 2 G * bakeActive(IApplicationThread _thread,4 D m P h U ProcessStatsService tb G ; J Y Fracker) {
...
thread = _thread;
mWindowProcessControllc 3 A [er.setThread(thread);
}
看到运用mWindowProcessController.setThread(thread)的确完结了IApplicationThread的赋值。这样就能够依据IApplicationThread是否为空判别进程是否存在了。
再看创立绑定Application的进程:IApplicationThread的bindApplication办法完结是客户端的ApplicationThread的bindApplication办法,它又运用H搬运到了ActivityThread的handleBindApplid J [ . fcation办法(从BiZ # r } fnder线程池搬运到主线程),看下handleBindApplication办法:
private void handleBindApplication(AppBindData data) {
...
final LoadedApk pi = getPacki 0 { $ } a ? n QageInfo(instrApp, data.compatInfo,
appContext.getCl1 : F m bassLoa5 o C m 9 ~ (der(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
appContext.get: / V ? l O SOpPackageName());
try {
//创立Instrumentation
final ClassLoader cl = instrConY f 9 t j 9text.getClasj ` { 1 8 3 # lsLoader();
mInstrumentation = (InstrumeG b A x L Dntation)
cl.loadb ^ 2 h { ) : / iClass(data.instrumentationName.getClassName()).newInstance();
}
...
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, ap. X c A h Y / pContext, component,
data.instrume3 F A % rntationWatchero 6 3 R, data.instrumentationUiAutomationConnection);
...
//创立Application
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
mInitialApplication = app;
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
...
try {
//内部调用4 y yApplX - 4 | [ication的onCreate办法
mInstrum$ N B $ ) - x $ uentation.callApplicationOnCreate(app);
}
...
}
首要便是创立ApplF e [ication,而且调用生命周期onCreate办法。你会发现在前面介绍的ActivityThread的performLaunchActivity办法中,也有同样的操作,只不过会9 j n先判别AK c _ B E C npplication是否已存在。也便是说,正常状况下Application的初始化是在handleBindApplication办法中的,而且是创立进程后调用的。performLaunchActivity中仅仅做了一个_ = 8 } v检测,反常状况Application不存在时才会创立。
再来看 根activity 的发动,回到上面AMS的attachApplicationLocked办法,调用了m] N i x 5 t C aAtmInternal.attachApplication办法,mAtmInternal是Acti^ S L r m : ( ` XvityTaskManagerInternal实例,详细完结是在ActivityTaskManagerService的内部类LocalService,去看看:
//ActivityTaskMV ` - ? y 7 ~ r VanagerService#LocalService
public| J y l y F c boolean attac2 ~ C ? jhApplication(v Y U -WindowProcessController wpc) throws RemoteException {
syn7 * W + &chronized (mGlobalLockWithoutBoost) {
re} y Q Qturn mRootActivT B J yityContaiv I E ner.attachApf s 5 ` b s iplication(wpc);
}
}
mRootActivi( T + E ? Z 6 5 jtyCong e U / I i ; : Btainer是RootA| k ~ctivityCM R %ontainer实例,看下它的attachApplication办法:
boolean attachApplication(WindowProcessControll* @ ~ Q Zer app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplay u Ds# a r R.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplaP U t Vy display = mActivitC 2 E K 2 GyDisplays.get(displayNdx);
final ActivityStack stack = display.getFocn U A W G g . YusedStack();
if (stack != null) {
stackR A ).getAllRunningVisibleActivitie^ c _ b S L G # )sLocked(mTmpActivityL9 m ` aist);
final ActivityRecord top = stack.toB t E M 8 w r _ YpRunningActivityLocm A f P D / x L ked();
final int siz9 ? Y * U 7 8 :ev 9 9 = ) & = mTmpActivityList.sk ` A oize[ [ _ * ` r x();
for (i& r p x j n ; ]nt i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (acti( 4 / Z ! =vity.app == null && app.mUk W s 6 `id == activity.info.applicationInfo.uid
&& processName.equals(ac@ z P U . O , ,tivity.processName)) {
try {
if (mStackSupervisor.real{ Y R Start; i vActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
}
...
}
}
}
}
iA u j ` mf (!didSomething) {
ensureActivitiesVisible(nullg f E C C | $ J j, 0, false /*Z V V N f L preserve_windows */);
}
return didSomething;
}
遍历activityH U , { 8 s = Q +栈,此刻理论上应该只要一个根activity,然后调m E + x W , 9 ] K用mStackSupervisor.[ 6 5 j l l prealStartActivityLocked办法,看到这儿咱们知道了,这儿就开端走上面# / { { F E + Z剖析过的流程了,即运用ClientTransaction会跨进程交给客户端,然后便是2.3、2.4两个末节的内容。
嗯,到这儿根activity的发动流程也剖析完了。
咱们发现,根activity的发动前 需求` B j Y i . ^ )创立运用进程,然后走到ActivityThread的main办法,敞开主线程循环,初始化并绑定Application、! V + J 3 !赋值IApplicationTh & S & | 5 1read,终究真实的发动进程和一般Az 9 D h %ctivity是一致的。
上面的流程图 弥补 根activity的逻辑,完好联系如下:
总结
关于 一般Activity 发动的流程的讲解,咱们分成了几个阶段:E g E ` 3 G _发动的建议、AMS的办理、线程切换、发动中心完结,知道了发动进程阅历了两次IPC,客户端到AMS、AMS到客户端,以及Activity创立和生命$ d t D ) 2 H x n周期的履行。 然后又在此基础上 弥补的根activity的发动:先创立运用进程,再绑定ApplicaE / U ` k ( t Ation,终究真实发动跟Activity。
本篇内容触及大量常识点,结合 IPC、Handler、Window等相关常识,这样能够对Andu 0 w k y x x Droid体系有愈加完好的知道。
好了,今日就到这儿,欢迎留言评论~
你的 点赞L @ p x Y [ E、评论、保藏、转发,是对/ 6 E B C我的巨大鼓舞!
欢迎重视我~ @ – K的 公 众 号: