IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Activity什么时候与Window建立联系? -> 正文阅读

[移动开发]Activity什么时候与Window建立联系?

1.摘要

我们知道Android SDK 主要目的就是为了View的显示。常见的是通过一个Activity进行显示界面。其中Activity会存在一个Window,View在Window容器中。Window作为Activity与View的通讯纽带。

问:Activity什么时候与Window建立联系?
答:Window是在Activity的attach()事件建立联系的

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)

从倒叙进行逻辑的研究即可

ZygoteInit RuntimeInit$MethodAndArgsCaller RuntimeInit ActivityThread Looper Handler ActivityThread$H TransactionExecutor LaunchActivityItem Activity run() invoke() main() loop() loopOnce() dispatchMessage() handleMessage() execute() executeCallbacks() execute() handleLaunchActivity() attach() ZygoteInit RuntimeInit$MethodAndArgsCaller RuntimeInit ActivityThread Looper Handler ActivityThread$H TransactionExecutor LaunchActivityItem Activity

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);

回顾一下
Window是在Activity的attach()事件建立联系的

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:46:02  更:2022-05-18 17:46:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:32:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码