Shadow icon indicating copy to clipboard operation
Shadow copied to clipboard

加载插件时,获取资源报错'android.content.res.Resources android.content.Context.getResources()' on a null object reference

Open HQlin opened this issue 4 years ago • 4 comments

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.(AppCompatDelegateImpl.java:329) at androidx.appcompat.app.AppCompatDelegateImpl.(AppCompatDelegateImpl.java:294) at androidx.appcompat.app.SkinAppCompatDelegateImpl.(SkinAppCompatDelegateImpl.java:25) at androidx.appcompat.app.SkinAppCompatDelegateImpl.get(SkinAppCompatDelegateImpl.java:18) at com.bzl.basever.ui.base.AbstractBaseActivity.getDelegate(AbstractBaseActivity.java:161) at androidx.appcompat.app.AppCompatActivity.attachBaseContext(AppCompatActivity.java:107) at com.tencent.shadow.core.runtime.PluginActivity.setHostContextAsBase(PluginActivity.java:62) at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.initPluginActivity(ShadowActivityDelegate.kt:173) at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:122) 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) 

你好,插件的资源管理有哪些要注意的地方呢?比如说插件有使用skin-support换肤、butterknife-gradle-plugin这些是否对宿主启动插件时加载资源有影响?

HQlin avatar Nov 11 '21 09:11 HQlin

从堆栈能确定这是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

shifujun avatar Nov 11 '21 09:11 shifujun

抱歉,因为是公司代码不能提供。我尝试自己构建用例,但是不能复现…

HQlin avatar Nov 12 '21 04:11 HQlin

你前面的堆栈显示这里试图在Activity的attachBaseContext方法调用super.attachBaseContext之前就getResource。

我起初看到androidx.appcompat.app.SkinAppCompatDelegateImpl的包名,以为这是官方的代码呢。搜了一下看起来不是。

我现在也写不出正常情况下在调用super.attachBaseContext之前就getResource能正常跑的例子。

shifujun avatar Nov 15 '21 06:11 shifujun

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

*/

HQlin avatar Nov 16 '21 09:11 HQlin