加载插件时,获取资源报错'android.content.res.Resources android.content.Context.getResources()' on a null object reference
2021-11-11 13:00:06.767 894-894/com.tencent.shadow.sample.host E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tencent.shadow.sample.host:plugin, PID: 894
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tencent.shadow.sample.host/com.tencent.shadow.sample.plugin.runtime.PluginDefaultProxyActivity}: java.lang.RuntimeException: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.RuntimeException: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:152)
at com.tencent.shadow.core.runtime.container.PluginContainerActivity.onCreate(PluginContainerActivity.java:84)
at android.app.Activity.performCreate(Activity.java:7994)
at android.app.Activity.performCreate(Activity.java:7978)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at com.tencent.shadow.core.runtime.ShadowContext.getResources(ShadowContext.java:108)
at androidx.appcompat.app.AppCompatActivity.getResources(AppCompatActivity.java:577)
at com.bzl.inner.ui.activity.MySplashActivity.getSuperResources(MySplashActivity.java:103)
at com.bzl.inner.ui.activity.MySplashActivity.getResources(MySplashActivity.java:37)
at android.view.ContextThemeWrapper.initializeTheme(ContextThemeWrapper.java:210)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:175)
at android.content.Context.obtainStyledAttributes(Context.java:770)
at androidx.appcompat.widget.TintTypedArray.obtainStyledAttributes(TintTypedArray.java:54)
at androidx.appcompat.app.AppCompatDelegateImpl.attachToWindow(AppCompatDelegateImpl.java:792)
at androidx.appcompat.app.AppCompatDelegateImpl.
你好,插件的资源管理有哪些要注意的地方呢?比如说插件有使用skin-support换肤、butterknife-gradle-plugin这些是否对宿主启动插件时加载资源有影响?
从堆栈能确定这是bug。
https://github.com/Tencent/Shadow/blob/15c0cd90fc7657856f51e49ad256fef2509670a9/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java#L103
这里依赖baseContext获取hostContext了,但被调用时attachBaseContext还没有执行到。
这里应该可以通过让ShadowContext主动持有hostContext来修复。我晚一些提PR。
虽然我应该能构造测试用例,但最好你也能提供一下你的测试代码。
说到换肤这个场景,Shadow能否支持主要取决于换肤的代码是如何实现的。如果它完全依赖公开API,比如通过Context、Resource机制来实现的,Shadow应该是能够支持的。比如之前也有issue提到的一个sdk,我测试过:https://github.com/Tencent/Shadow/issues/595#issuecomment-911343885
抱歉,因为是公司代码不能提供。我尝试自己构建用例,但是不能复现…
你前面的堆栈显示这里试图在Activity的attachBaseContext方法调用super.attachBaseContext之前就getResource。
我起初看到androidx.appcompat.app.SkinAppCompatDelegateImpl的包名,以为这是官方的代码呢。搜了一下看起来不是。
我现在也写不出正常情况下在调用super.attachBaseContext之前就getResource能正常跑的例子。
androidx.appcompat.app.SkinAppCompatDelegateImpl是skin.support:skin-support-appcompat:4.0.4库的,临时解决方法是我把插件的父类activity舍弃skin.support换肤功能,注释以下代码:
/**
* Android Skin Support 需要添加的配置
@NonNull
@Override
public AppCompatDelegate getDelegate() {
return SkinAppCompatDelegateImpl.get(this, this);
}
*/