android.view.InflateException扩展类android.webkit.WebView时出错

Val*_*rio 48 java android webview

我有这个试图杀了我的问题.

在Lollipop(API 22)中,每次在我的应用程序中我都会显示webview,应用程序崩溃了.我的android开发者控制台中有多个与此事件相关的崩溃.

无需说它适用于Android 4,6和7.

阅读堆栈跟踪(在本文末尾发布),有些东西让我感到困惑

Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003
Run Code Online (Sandbox Code Playgroud)

我在生成的R.java中搜索没有任何运气,显然是因为ID不存在,但值得一试.

谷歌搜索问题似乎与棒棒糖处理webview的方式有关.我根据我在GDC的崩溃记者找到的设备开始使用棒棒糖的新AVD,我可以重现这个问题.

请帮我!


完整堆栈跟踪:

android.view.InflateException: Binary XML file line #7: Error inflating class android.webkit.WebView
                  at android.view.LayoutInflater.createView(LayoutInflater.java:633)
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
                  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682)
                  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741)
                  at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                  at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67)
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295)
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682)
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5254)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
               Caused by: java.lang.reflect.InvocationTargetException
                  at java.lang.reflect.Constructor.newInstance(Native Method)
                  at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
                  at android.view.LayoutInflater.createView(LayoutInflater.java:607)
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55) 
                  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682) 
                  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741) 
                  at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
                  at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67) 
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295) 
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801) 
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682) 
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541) 
                  at android.os.Handler.handleCallback(Handler.java:739) 
                  at android.os.Handler.dispatchMessage(Handler.java:95) 
                  at android.os.Looper.loop(Looper.java:135) 
                  at android.app.ActivityThread.main(ActivityThread.java:5254) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
               Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003
                  at android.content.res.Resources.getText(Resources.java:299)
                  at android.content.res.Resources.getString(Resources.java:385)
                  at com.android.org.chromium.content.browser.ContentViewCore.setContainerView(ContentViewCore.java:684)
                  at com.android.org.chromium.content.browser.ContentViewCore.initialize(ContentViewCore.java:608)
                  at com.android.org.chromium.android_webview.AwContents.createAndInitializeContentViewCore(AwContents.java:631)
                  at com.android.org.chromium.android_webview.AwContents.setNewAwContents(AwContents.java:780)
                  at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:619)
                  at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:556)
                  at com.android.webview.chromium.WebViewChromium.initForReal(WebViewChromium.java:311)
                  at com.android.webview.chromium.WebViewChromium.access$100(WebViewChromium.java:96)
                  at com.android.webview.chromium.WebViewChromium$1.run(WebViewChromium.java:263)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.drainQueue(WebViewChromium.java:123)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue$1.run(WebViewChromium.java:110)
                  at com.android.org.chromium.base.ThreadUtils.runOnUiThread(ThreadUtils.java:144)
                  at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.addTask(WebViewChromium.java:107)
                  at com.android.webview.chromium.WebViewChromium.init(WebViewChromium.java:260)
                  at android.webkit.WebView.<init>(WebView.java:554)
                  at android.webkit.WebView.<init>(WebView.java:489)
                  at android.webkit.WebView.<init>(WebView.java:472)
                  at android.webkit.WebView.<init>(WebView.java:459)
                  at java.lang.reflect.Constructor.newInstance(Native Method) 
                  at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
                  at android.view.LayoutInflater.createView(LayoutInflater.java:607) 
                  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55) 
                  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682) 
                  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741) 
                  at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
                  at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
                  at it.artecoop.ibreviary.WebViewFragment.onCreateView(WebViewFragment.java:67) 
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113) 
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295) 
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801) 
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682) 
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:541) 
                  at android.os.Handler.handleCallback(Handler.java:739) 
                  at android.os.Handler.dispatchMessage(Handler.java:95) 
                  at android.os.Looper.loop(Looper.java:135) 
                  at android.app.ActivityThread.main(ActivityThread.java:5254) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
Run Code Online (Sandbox Code Playgroud)

Pra*_*ira 51

如果您正在使用androidx.appcompat:appcompat:1.1.0并且不想降级androidx.appcompat:appcompat:1.0.2或升级到androidx.appcompat:appcompat:1.2.0-alpha03,则在 Google 问题跟踪器的此评论中描述了另一种解决方案。

我注意到在调用 applyOverrideConfiguration 之后,Context.getAssets()Context.getResources().getAssets()没有返回相同的 AssetManager 对象。返回的AssetManagerContext.getAssets()无法访问其他包(包括系统WebView包)中的资源,导致WebView崩溃。如果我覆盖Context.getAssets()return getResources().getAssets(),问题就消失了。

根据该评论,您可以覆盖getAssets()WebView 的 Activity 中的 ,以便它返回getResources().getAssets()来解决问题。

爪哇

@Override
public AssetManager getAssets() {
    return getResources().getAssets();
}
Run Code Online (Sandbox Code Playgroud)

科特林

override fun getAssets(): AssetManager {
    return resources.assets
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案+1 (3认同)

小智 46

如果您使用“ androidx.appcompat:appcompat:1.1.0”,请尝试使用“ androidx.appcompat:appcompat:1.0.2”。似乎1.1.0无法处理android 5.1.1中的webview错误。

  • 有与此相关的问题:https://issuetracker.google.com/issues/141132133 (5认同)
  • 是否存在用于保持1.1.0并修复此问题的错误修复程序?我们依赖于1.0.2中不存在的某些功能,并且似乎1.1.0的某些alpha或beta版本没有此错误。 (3认同)
  • 就像今天一样,降级不起作用,就我而言,https://issuetracker.google.com/issues/141132133 的解决方案有效:“也许解决此问题的最简单方法是强制 Gradle 将版本设置为1.1.0-rc01。将其添加到您的 gradle 文件中。configurations.all {resolutionStrategy {force 'androidx.appcompat:appcompat:1.1.0-rc01' } }" (3认同)
  • `androidx.appcompat:appcompat:1.2.0-alpha03` 也可以工作 (3认同)
  • 升级到实现'androidx.appcompat:appcompat:1.2.0-beta01解决了这个问题,它对上述版本(6.0及以上)有任何副作用吗? (3认同)
  • 是的,清理干净,谢谢!我正在使用beta01,一切似乎都很好。我将继续使用它,因为无论如何使用1.1.0并没有明显的好处。 (2认同)

Spa*_*son 33

警告:这种解决方法也可能会破坏某些功能;查看评论以获取详细信息

如果您想从XML布局中扩充 WebView,可以将其包装在一个漂亮的小子类中(基于ikostet的答案):

public class LollipopFixedWebView extends WebView {
    public LollipopFixedWebView(Context context) {
        super(getFixedContext(context));
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs) {
        super(getFixedContext(context), attrs);
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(getFixedContext(context), attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
        super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing);
    }

    public static Context getFixedContext(Context context) {
        return context.createConfigurationContext(new Configuration());
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:现在与Kotlin更好

class LollipopFixedWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : WebView(context.createConfigurationContext(Configuration()), attrs, defStyleAttr, defStyleRes)
Run Code Online (Sandbox Code Playgroud)

  • 关于此变通办法,请注意一点:用空白Context实例化WebView可能会导致意外的副作用。例如,WebView中的ActionModes可能不再起作用(即长按以突出显示文本)。 (4认同)
  • 正如@DmitryBrant所说的那样,在执行此操作时要非常小心,因为这会破坏一些内容,包括“下拉字段”和“长按以突出显示文本”! (3认同)
  • 在2019年仍然是一个问题,它可以工作,但我不知道为什么/如何,如果对此进行解释会很好。我也收到警告,永远不要在第四个构造函数上使用“ public LollipopFixedWebView(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes){” (2认同)

sna*_*msm 21

我的建议是Configuration仅在“原始版本”引起问题时才使用custom / new ,因此仅在Lollipop上使用。@SpaceBizon代码在Android 8.x,9和Q(当前为beta)上运行良好,直到每次选择/下拉按均不会显示AlertDialog选择器,而不会出现内存泄漏...下面的固定getFixedContext方法带有“正确的”正确版本代码

public class LollipopFixedWebView extends WebView {

    public LollipopFixedWebView(Context context) {
        super(getFixedContext(context));
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs) {
        super(getFixedContext(context), attrs);
    }

    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(getFixedContext(context), attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
    }

    private static Context getFixedContext(Context context) {
        if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23) // Android Lollipop 5.0 & 5.1
            return context.createConfigurationContext(new Configuration());
        return context;
    }
}
Run Code Online (Sandbox Code Playgroud)


S. *_*sel 20

如果您不依赖 DayNight 主题切换(或其他 UiMode 事件),您可以将android:configChanges="uiMode" 添加到 webview 活动清单,以防止 AppCompatDelegate 更新资源配置,从而弄乱 webview 膨胀。


小智 14

尝试用于创建webview:

mWebView = new WebView(getActivity().createConfigurationContext(new Configuration()));
Run Code Online (Sandbox Code Playgroud)


A R*_*ran 11

如果您使用的是androidx.appcompat:appcompat:1.1.0,请更改为androidx.appcompat:appcompat:1.0.2,或者如果您想使用DayNight主题,请按如下所示在活动中覆盖applyOverrideConfiguration。(请注意:这需要在从“黑暗主题”切换到“浅主题”时,重新启动应用,反之亦然)。

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
        if (Build.VERSION.SDK_INT in 21..25 && (resources.configuration.uiMode == AppConstants.appContext.resources.configuration.uiMode)) {
                return
        }
        super.applyOverrideConfiguration(overrideConfiguration)
}
Run Code Online (Sandbox Code Playgroud)

  • 我在java中的解决方法似乎对我有用(很抱歉格式很糟糕,但这不是一个新的答案,只是一个端口): ```@Override public void applyOverrideConfiguration(Configuration overrideConfiguration) { if (Build.VERSION.SDK_INT &gt;= 21 &amp;&amp; Build.VERSION.SDK_INT &lt;= 25) { return; } super.applyOverrideConfiguration(overrideConfiguration); }``` (3认同)
  • 这是导致此崩溃的修订-https://android.googlesource.com/platform/frameworks/support/+/26079d87c79a64829f036236353fac1dae4e0613%5E%21/#F2。因此,根据代码,当未安装Google Play商店且Android Webview版本小于50的设备中的API 21..25中将发生崩溃。 (2认同)

Hot*_*eam 10

再尝试解决问题。应该在您的活动中覆盖此方法:

    @Override
    public void applyOverrideConfiguration(final Configuration overrideConfiguration) {
        if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 25) {
            overrideConfiguration.uiMode &= ~Configuration.UI_MODE_NIGHT_MASK;
        }
        super.applyOverrideConfiguration(overrideConfiguration);
    }
Run Code Online (Sandbox Code Playgroud)


Man*_*uel 6

我能够在模拟器中重现 API 21 上的崩溃。

所以我尝试将其添加到实现中,如文档中所述:

dependencies {
    def appcompat_version = "1.1.0"

    implementation "androidx.appcompat:appcompat:$appcompat_version"
    // For loading and tinting drawables on older versions of the platform
    implementation "androidx.appcompat:appcompat-resources:$appcompat_version"
}
Run Code Online (Sandbox Code Playgroud)

添加appcompat-resources没有解决问题。

也许未来的版本会,但我想提一下,似乎有一个补充资源库可以解决这个问题。因此,当尝试使用 的新版本修复此问题时appcompat,请添加appcompat-resources具有相同版本的库。

恢复为androidx.appcompat:appcompat:1.0.2确实解决了该问题作为解决方法。


小智 6

下面的代码将解决这个问题。请将其添加到您的Activity

@Override 
public AssetManager getAssets() {
    return getResources().getAssets(); 
}
Run Code Online (Sandbox Code Playgroud)


F.M*_*sir 5

我使用了这个来源的最新版本。请根据您认为最好的方式检查并使用您自己的。

如果您想跳过,下面的实现可以解决该问题:

implementation 'androidx.appcompat:appcompat:1.2.0'
Run Code Online (Sandbox Code Playgroud)