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

时间:2016-12-07 18:55:30

标签: java android webview

我有这个问题试图杀了我。

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

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

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

Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003

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

Google搜索问题似乎与lollipop处理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) 

20 个答案:

答案 0 :(得分:59)

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

答案 1 :(得分:49)

如果您使用的是androidx.appcompat:appcompat:1.1.0,并且不想降级到androidx.appcompat:appcompat:1.0.2或升级到androidx.appcompat:appcompat:1.2.0-alpha03,那么Google问题的this comment中介绍了另一种解决方案跟踪器。

我注意到,在调用applyOverrideConfiguration之后,Context.getAssets()Context.getResources().getAssets()没有返回相同的AssetManager对象。从Context.getAssets()返回的AssetManager无法访问其他程序包(包括系统WebView程序包)中的资源,从而导致WebView崩溃。如果我重写Context.getAssets()以返回getResources().getAssets(),问题就解决了。

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

Java

@Override
public AssetManager getAssets() {
    return getResources().getAssets();
}

科特琳

override fun getAssets(): AssetManager {
    return resources.assets
}

答案 2 :(得分:13)

如果您使用的是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)
}

答案 3 :(得分:10)

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

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

编辑:现在使用Kotlin

更好
class LollipopFixedWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : WebView(context.createConfigurationContext(Configuration()), attrs, defStyleAttr, defStyleRes)

答案 4 :(得分:8)

尝试用于创建webview:

mWebView = new WebView(getActivity().createConfigurationContext(new Configuration()));

答案 5 :(得分:6)

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

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

答案 6 :(得分:6)

以下代码将解决此问题。请将其添加到您的Activity中:

@Override 
public AssetManager getAssets() {
    return getResources().getAssets(); 
}

答案 7 :(得分:6)

如果您不依赖DayNight主题切换(或其他UiMode事件),则可以将 android:configChanges =“ uiMode” 添加到Webview活动清单中,以防止AppCompatDelegate更新资源配置,从而防止更新弄乱了网络视图的通货膨胀。

答案 8 :(得分:3)

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

因此,我尝试将其添加到实现中,如docs中所述:

    function zoomed() {

        let transform = d3.event.transform

        transform.x = Math.min(0, Math.max(transform.x, width - width * transform.k));
        transform.y = Math.min(0, Math.max(transform.y, height - height * transform.k));

        g.attr("transform", transform);

        d3.selectAll(".markar-path").attr("transform", (d) => { return 4/d3.event.scale()})




    }

添加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" } 不能解决问题。

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

恢复为appcompat-resources确实可以解决此问题。

答案 9 :(得分:3)

我使用了this source中的最新版本。请根据您认为最好的方法进行检查并使用自己的方法。

如果您想跳过,请通过以下实现解决此问题:

npm install

答案 10 :(得分:2)

/**
 * Customized WebView to avoid crashing on Android 5 and 6 (API level 21 to 23)
 * If the Android System WebView is old and is not updated, the WebView view inflation fails.
 * To reproduce the issue, try on OS 5 or 6 with Android System WebView 72.0.3626.76 (this version is just a reference point from being which we saw no crashes)
 */
class BrilliantWebView : WebView {

   companion object {
       private fun getBrilliantContext(context: Context?) =
            if (!OSUtils.hasNougat()) // OS < 24 or OS < 7.0
                context?.createConfigurationContext(Configuration())
            else
                context
    }

   constructor(context: Context?) : super(getBrilliantContext(context))
   constructor(context: Context?, attrs: AttributeSet?) : super(getBrilliantContext(context), attrs)
   constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(getBrilliantContext(context), attrs, defStyleAttr)
}

答案 11 :(得分:2)

戴文锦也很适合我。 但是将androidx.appcompat:appcompat:1.1.0降级到1.0.2不会成功。

我从

降级了所有以前升级的androidx版本
library(shiny)

ui <- shinyUI(
  navbarPage(
    title = "This is the navbar",
    id = "navbarID",
    tabPanel("Tab 1"),
    tabPanel("Tab 2"),
    tabPanel("Save")
  )
)

server <- function(input, output, session) {
  observeEvent(input$navbarID, {
    if (input$navbarID == "Save") {
      print("You just clicked 'Save' in the navbar")
    }
  })
}

shinyApp(ui = ui, server = server)

返回

implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha10'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta04'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta04'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.core:core:1.2.0-alpha04'

提醒您,Google的代码到目前为止还没有错误,并且没有经过良好的测试,并且永远不要轻率地升级版本。

答案 12 :(得分:2)

AppCompat 1.2.0-alpha02今天发布,因此您可以使用

implementation 'androidx.appcompat:appcompat:1.2.0-alpha02'

这将解决Lollipop上的WebView问题。

答案 13 :(得分:2)

我能够在Nexus 7 API 22上重现此问题。此问题已通过将平板电脑的Android系统WebView版本从 39版(2237560-arm)更新为版而得以解决79.0.3945.136

这不是我可以控制的,但是如果您需要帮助某人立即使用您的应用程序,这是一个解决方案。

答案 14 :(得分:1)

就我而言,方法存在问题

fun getUserId(): Int = userId
MainActivity的

。我不知道为什么它会影响WebViewgetUserId()既不被覆盖,也不Activity类的公共方法。如果我重命名或删除此方法,WebView将开始打开。还试图改变

private var userId: Int = 0

var userId: Int = 0
    private set

导致相同的异常。我了解到,当遇到异常时:Caused by: java.lang.SecurityException: Permission Denial: null asks to run as user 123456 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS。在那种情况下,user = 123456实际上是我的授权用户,该用户在某些请求中使用,而不是在WebView中使用。我怀疑Android使用userId作为其进程的本地user_id。

许多其他人注意到,我们可以使用appcompat:1.1.01.0.2并扩展WebView类。在没有Google Play服务的模拟器21中,长时间触摸文本标签会导致WebView崩溃,但是在典型设备上,一切正常。

答案 15 :(得分:1)

我的建议是仅在“原始版本”引起问题时才使用自定义/新Configuration,因此仅在棒棒糖上使用。 @SpaceBizon代码可以正常运行,直到Android 8.x,9和Q(当前为beta)时,每次选择/下拉按均不会显示AlertDialog选择器,而不是发生内存泄漏...低于固定的{{1} }带有“正确”版本代码的方法

getFixedContext

答案 16 :(得分:0)

问题已解决,我将其降级为实现androidx.appcompat:appcompat:1.0.2'

答案 17 :(得分:0)

作为一个旁注,即使我降级到1.0.2,我仍然挣扎了一段时间,只是因为我似乎通过androidx.constraintlayout:constraintlayout:2.0.0-beta3对appcompat:1.1.0具有传递依赖。 。一旦我将其降级为constraintlayout:1.1.3,一切都很好

(根据https://issuetracker.google.com/issues/141351441问题将很快通过appcompat:1.2.0-alpha02修复)

答案 18 :(得分:0)

我没有更改任何依赖的版本,而是以编程方式实现了webView的生成作为解决方案。

问题实际上看起来像是从xml文件读取布局开始的。因此,如果编程方式适合您,请检查波纹管样品。

private WebView generateWebView(){
    WebView wv = new WebView(YourContext);
    wv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    wv.setFitsSystemWindows(false); // your preferences
    wv.setVerticalScrollBarEnabled(false); // your preferences
    wv.setPadding(15,15,15,15); // your preferences
    return wv;
}

不仅仅是添加到父视图中

LinearLayout scrollContainer = findViewById(R.id.scrollContainer);
scrollContainer.addView(generateWebView());

答案 19 :(得分:-4)

检查版本。 Androidx appcompat和Google材料版本始终保持相同。

implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation "androidx.cardview:cardview:1.0.0"

enter image description here