我们知道Android SDK 主要目的就是为了View的显示。常见的是通过一个Activity进行显示界面。其中Activity会存在一个Window,View在Window容器中。Window作为Activity与View的通讯纽带。
问:Activity什么时候与Window建立联系?
答:Window是在Activity的attach()事件建立联系的
本文很啰嗦,但是只是想说明,研究系统源码不复杂,有方法和技巧就行。例如最原始的打印日志堆栈,既可以理清一部分思路
2.分析思路在不了解AMS架构的情况下,可以打印Activity启动逻辑堆栈,快速找到问题答案。
2.1 Hello work app中新增堆栈函数通过打印线程的堆栈:Thread.currentThread().stackTrace
package com.sufadi.helleworld
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 查看函数调用流程
val threadStack = Thread.currentThread().stackTrace.toList()
for (stack in threadStack) {
Log.d("helloworld", stack.toString())
}
}
}
2.2 根据堆栈日志查看应用冷启动流程
通过堆栈接下来的思路很简单了,查看顺序就可以找到最先new出Window的地方。即本问题的答案。
helloworld: java.lang.Thread.getStackTrace(Thread.java:1724)
helloworld: com.sufadi.helleworld.MainActivity.onCreate(MainActivity.kt:14)
helloworld: android.app.Activity.performCreate(Activity.java:8120)
helloworld: android.app.Activity.performCreate(Activity.java:8100)
helloworld: android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1340)
helloworld: android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3783)
helloworld: android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3976)
helloworld: android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
helloworld: android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
helloworld: android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
helloworld: android.app.ActivityThread$H.handleMessage(ActivityThread.java:2340)
helloworld: android.os.Handler.dispatchMessage(Handler.java:106)
helloworld: android.os.Looper.loopOnce(Looper.java:217)
helloworld: android.os.Looper.loop(Looper.java:309)
helloworld: android.app.ActivityThread.main(ActivityThread.java:8151)
helloworld: java.lang.reflect.Method.invoke(Native Method)
helloworld: com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:579)
helloworld: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1045)
从倒叙进行逻辑的研究即可
2.2.1 ZygoteInit->>RuntimeInit$MethodAndArgsCaller:run()frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
1042 // We're in the child process and have exited the select loop. Proceed to execute the
1043 // command.
1044 if (caller != null) {
1045 caller.run();
1046 }
}
2.2.2 RuntimeInit->>RuntimeInit:invoke()
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
反射invoke,旨在反射调用 ActivityThread.main
static class MethodAndArgsCaller implements Runnable {
577 public void run() {
578 try {
579 mMethod.invoke(null, new Object[] { mArgs });
...
}
2.2.3 RuntimeInit->>ActivityThread:main()
frameworks/base/core/java/android/app/ActivityThread.java
这个是APP的main函数来着。看了下main这里主要启动Loop进行生产者消费者模型,进行Acitivity所有活动的处理,将类似生命周期、点击事件等各种都是活动的事件,转化为Message。通过Handler进行管理。故使用Looper.loop()开启无限循环,查看是否有新消息需要处理。
public static void main(String[] args) {
8151 Looper.loop();
}
2.2.4 ActivityThread->>Looper:loop()
frameworks/base/core/java/android/os/Looper.java
通过Handler进行管理。故使用Looper.loop()开启无限循环,查看是否有新消息需要处理。
public static void loop() {
308 for (;;) {
309 if (!loopOnce(me, ident, thresholdOverride)) {
310 return;
311 }
312 }
}
2.2.5 Looper->>Looper:loopOnce()
helloworld: android.os.Looper.loopOnce(Looper.java:217)
处理消息msg.target.dispatchMessage
private static boolean loopOnce(final Looper me,
216 try {
217 msg.target.dispatchMessage(msg);
}
2.2.6 Looper->>Handler:dispatchMessage()
helloworld: android.os.Handler.dispatchMessage(Handler.java:106)
97 public void dispatchMessage(@NonNull Message msg) {
98 if (msg.callback != null) {
99 handleCallback(msg);
100 } else {
101 if (mCallback != null) {
102 if (mCallback.handleMessage(msg)) {
103 return;
104 }
105 }
106 handleMessage(msg);
107 }
108 }
2.2.7 Handler->>ActivityThread$H.handleMessage
helloworld: android.app.ActivityThread$H.handleMessage(ActivityThread.java:2340)
Handler的消息传递链路
2338 case EXECUTE_TRANSACTION:
2339 final ClientTransaction transaction = (ClientTransaction) msg.obj;
2340 mTransactionExecutor.execute(transaction);
2341 if (isSystem()) {
2342 // Client transactions inside system process are recycled on the client side
2343 // instead of ClientLifecycleManager to avoid being cleared before this
2344 // message is handled.
2345 transaction.recycle();
2346 }
2347 // TODO(lifecycler): Recycle locally scheduled transactions.
2348 break;
2.2.8 ActivityThread$H->>TransactionExecutor:execute()
helloworld: android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
TransactionExecutor处理ClientTransaction
69 public void execute(ClientTransaction transaction) {
95 executeCallbacks(transaction);
2.2.9 TransactionExecutor->>TransactionExecutor:executeCallbacks()
helloworld: android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
executeCallbacks()启动Activity
104 public void executeCallbacks(ClientTransaction transaction) {
135 item.execute(mTransactionHandler, token, mPendingActions);
2.2.10 TransactionExecutor->>LaunchActivityItem:execute()
helloworld: android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
可看 handleLaunchActivity
98 @Override
99 public void execute(ClientTransactionHandler client, IBinder token,
100 PendingTransactionActions pendingActions) {
101 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
102 ActivityClientRecord r = client.getLaunchingActivity(token);
103 client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
104 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
105 }
2.2.11 LaunchActivityItem->>ActivityThread:handleLaunchActivity()
helloworld: android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3976)
frameworks/base/core/java/android/app/ActivityThread.java
可以看到 Activity 的对象被实例化了,这个时候我们要开始留心观察Window类什么时候被实例化
这个 ActivityThread:handleLaunchActivity() 做的事情还挺多的,Application和Window都开始被创建了
3935 @Override
3936 public Activity handleLaunchActivity(ActivityClientRecord r,
3937 PendingTransactionActions pendingActions, Intent customIntent) {
...
3720 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
3739 Window window = null;// 注意看window对象
...
3752 activity.attach(appContext, this, getInstrumentation(), r.token,
3753 r.ident, app, r.intent, r.activityInfo, title, r.parent,
3754 r.embeddedID, r.lastNonConfigurationInstances, config,
3755 r.referrer, r.voiceInteractor, window, r.configCallback,
3756 r.assistToken, r.shareableActivityToken);
...
2.2.13 ActivityThread->>Activity:attach()
重点看下将 window = null 传进去是干啥
frameworks/base/core/java/android/app/Activity.java
看到new了,我们现在知道答案了:Window是在Activity的attach()事件建立联系的
7997 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
7998 final void attach(Context context, ActivityThread aThread,
7999 Instrumentation instr, IBinder token, int ident,
8000 Application application, Intent intent, ActivityInfo info,
8001 CharSequence title, Activity parent, String id,
8002 NonConfigurationInstances lastNonConfigurationInstances,
8003 Configuration config, String referrer, IVoiceInteractor voiceInteractor,
8004 Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
8005 IBinder shareableActivityToken) {
...
8009
8010 mWindow = new PhoneWindow(this, window, activityConfigCallback);
回顾一下
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)