Activity什么时候与Window建立联系?

Activity什么时候与Window建立联系?,第1张

1.摘要

我们知道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);

回顾一下

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/916819.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存