ActivityThread读书笔记2-onResume的调用时机

本文探讨了Android应用中ActivityThread的角色,它如何管理ApplicationThread并与AMS通信。通过分析onResume()的调用时机,揭示了onResume()并不等同于Activity对用户完全可见,而是在performResumeActivity方法中触发,包括调用onResume()、绘制UI以及makeVisible()方法。这一发现挑战了对Activity生命周期的传统认知。

之前一片文章,学习了ActivityThread是App的真正入口,他在内部维护了一个ApplicationThread对象,他和远程的ams进行通信。当创建Activity时,调用ams通过Binder机制调用ApplicationThread对象的方法,进而调用ActivityThread中的handleResumeActivity方法,最终调用Activity中的onResume()方法。

在以前的印象中onResume()这个生命周期表示当前的Activity对用户可见,这是不是表示onResume()之前页面就已经绘制出来了呢?Activity的UI实在什么时候开始绘制的呢?带着这些疑问来研究研究。。。

/**
 * <p>Keep in mind that onResume is not the best indicator that your activity
 * is visible to the user; a system window such as the keyguard may be in
 * front.  Use {@link #onWindowFocusChanged} to know for certain that your
 * activity is visible to the user (for example, to resume a game).
 * 只有当onWindowFocusChanged方法被调用的时候,才能确认当前的Activity对用户的可见的
 */
@CallSuper
protected void onResume() {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
    getApplication().dispatchActivityResumed(this);
    mActivityTransitionState.onResume();
    mCalled = true;
}

我去,颠覆三观,一直以为onResume的时候,Activity就对用户可见了。

为了研究这个问题,还得回到Act

`Instrumentation: Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory` 这一错误通常是由于 `ActivityThread` 未初始化,可能是应用创建的 `Instrumentation` 所导致的。以下是一些可能的解决方案: #### 检查应用签名 在开发调试时,可尝试为 debug 包添加签名。在 app 的 `build.gradle` 中添加如下配置: ```groovy signingConfigs { debug { storeFile file('../keystore/xxx.jks') // 签名文件路径 storePassword "xxxx" keyAlias "xxxx" keyPassword "xxxx" // 签名密码 println("====== signingConfigs.debug ======") } } buildTypes { debug { signingConfig signingConfigs.debug } // 其他构建类型配置 } ``` 这样做可能会解决因未签名而引发的问题[^4]。 #### 检查 `Instrumentation` 代码 查看代码中是否存在手动创建 `Instrumentation` 实例的情况。若有,要确保 `ActivityThread` 已正确初始化。在 `Instrumentation` 调用 `newApplication` 方法时,会检查 `ActivityThread` 是否初始化,若未初始化则会禁用 `AppComponentFactory`。以下是 `newApplication` 方法的示例代码: ```java public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = getFactory(context.getPackageName()) .instantiateApplication(cl, className); app.attach(context); return app; } private AppComponentFactory getFactory(String pkg) { if (pkg == null) { Log.e(TAG, "No pkg specified, disabling AppComponentFactory"); return AppComponentFactory.DEFAULT; } if (mThread == null) { Log.e(TAG, "Uninitialized ActivityThread, likely app-created Instrumentation," + " disabling AppComponentFactory", new Throwable()); return AppComponentFactory.DEFAULT; } LoadedApk apk = mThread.peekPackageInfo(pkg, true); // This is in the case of starting up "android". if (apk == null) apk = mThread.getSystemContext().mPackageInfo; return apk.getAppFactory(); } ``` 要确保在调用这些方法时,`ActivityThread` 已正确初始化[^3]。 #### 检查依赖库 某些第三方库可能会干扰 `Instrumentation` 和 `ActivityThread` 的正常工作。可尝试逐个排除依赖库,查看问题是否依然存在。 #### 清理和重建项目 在 Android Studio 中,选择 `Build` -> `Clean Project` 清理项目,然后选择 `Build` -> `Rebuild Project` 重建项目,以确保项目文件的完整性。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值