最近看了不少源码,然而看源码这种事情当时分析清楚了,下一次再看又感觉不太熟悉,毕竟Read The Fucking Source Code 嘛。所以把我感觉重要的点略微记录一下。
一、在onLayout()方法中调用requestLayot()
https://blog.csdn.net/litefish/article/details/53645942?utm_source=itdadao&utm_medium=referral
这篇博文基本上已经总结比较清楚了,然而我实际测试的时候把requestLayout()放在super.onLayout()之前的时候,不会进入后续的第二次layout。一开始还不太理解,后来仔细查看源码发现在getValidLayoutRequesters()这个方法中,调用requestLayout的view在layout结束之后PFLAG_FORCE_LAYOUT置位,所以返回值会变为null,所以第二次layout将不会执行。但是如果这样写有一个问题,有时候设置某些属性的是在measure中实现,这样写不会进入第二次的measure,layout,会导致无法出现期望的结果。所以如果要在onLayout方法中调用requestLayot,需要写在super.onLayout()的后面。我实际测试LinearLayout中设置padding,是可以写在前面的。
二、Activity的finish()源码分析
https://blog.csdn.net/zjd934784273/article/details/73930855
当时看这篇文章主要是想了解下finish以及onActivityResult()的调用流程。这里总结一下吧。
主要方法是ActivityStack的resumeTopActivityInnerLocked方法,这里主要就是
{
// Find the next top-most activity to resume in this stack that is not finishing and is
// focusable. If it is not focusable, we will fall into the case below to resume the
// top activity in the next focusable task.
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
// Deliver all pending results.
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
next.app.thread.scheduleSendResult(next.appToken, a);
}
}
if (next.newIntents != null) {
next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
}
......
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
mService.isNextTransitionForward(), resumeAnimOptions);
}
scheduleResumeActivity会调用onReStart–>onStart—>onResume
所以onActivityResult以及newIntent会在这些声明周期之前执行。
在window中添加view,并执行measure,layout之类的方法是在onResume之后执行的,所以在activity的onResume中无法获取view的宽高
next我们通过注释知道是找到栈顶的activity,也就是接下来要显示的activity。
next的results是在finish的时候设置的,最终方法是ActivityStack的finishActivityResultsLocked()。
private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
// send the result
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
+ " who=" + r.resultWho + " req=" + r.requestCode
+ " res=" + resultCode + " data=" + resultData);
if (resultTo.userId != r.userId) {
if (resultData != null) {
resultData.prepareToLeaveUser(r.userId);
}
}
if (r.info.applicationInfo.uid > 0) {
mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
resultTo.packageName, resultData,
resultTo.getUriPermissionsLocked(), resultTo.userId);
}
resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
resultData);
r.resultTo = null;
}
else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
// Make sure this HistoryRecord is not holding on to other resources,
// because clients have remote IPC references to this object so we
// can't assume that will go away and want to avoid circular IPC refs.
r.results = null;
r.pendingResults = null;
r.newIntents = null;
r.icicle = null;
}
如果A启动B,那么B调用finish,这里的r就是B,r.resultTo就是A,所以在A的results中加入结果,在之后A将要显示的时候就会判断results是否大于0来确认是否需要调用onActivityResult()。