Android.view.InflateException Ошибка раздувания класса android.webkit.WebView

У меня есть эта проблема, которая пытается убить меня.

В Lollipop (API 22) каждый раз в моем приложении я показываю веб-просмотр, сбой приложения. У меня несколько сбоев в моей консоли разработчика Android, связанных с этим событием.

Не нужно говорить, что он работает на Android 4, 6 и 7.

Чтение трассировки стека (опубликовано в конце этого сообщения), что-то меня пугает

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

Я искал в сгенерированном R.java без везения, очевидно, потому что идентификатор не существует, но стоит попробовать.

Похоже, что проблема вокруг проблемы связана с тем, как леденец обрабатывает веб-просмотр. Я начал новый AVD с lollipop на основе устройства, которое я нашел в репортере аварии в GDC, и я могу воспроизвести проблему.

Пожалуйста, помогите мне!


Полная трассировка стека:

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) 

Ответ 1

Предупреждение: этот обходной путь может также сломать некоторые вещи; подробности смотрите в комментариях

Если вы хотите надуть WebView из макета XML, вы можете заключить его в симпатичный маленький подкласс (на основе ответа 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());
    }
}

ОБНОВЛЕНИЕ: теперь еще приятнее с Kotlin

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

Ответ 2

если вы используете "androidx.appcompat: appcompat: 1.1.0", попробуйте вместо "androidx.appcompat: appcompat: 1.0.2". Кажется, что 1.1.0 не обрабатывает ошибку с веб-просмотром в Android 5.1.1.

Ответ 3

Попробуйте использовать веб-просмотр:

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

Ответ 4

Мой совет - использовать пользовательскую/новую Configuration только тогда, когда "оригинальная" вызывает проблемы, поэтому только на Lollipop. Код @SpaceBizon работал хорошо до Android 8.x, на 9 и Q (текущая бета) каждое нажатие на выбор /AlertDialog не будет показывать AlertDialog выбора AlertDialog, вместо этого происходит утечка памяти... ниже фиксированного метода getFixedContext с "iffed" правильной версией код

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

Ответ 5

Если вы используете 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)
}

Ответ 6

戴 文锦 был прав и для меня. Но понижение версии androidx.appcompat: appcompat: 1.1.0 до 1.0.2 не удалось.

Я понизил все мои ранее обновленные версии Androidx с

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'

вернуться к

implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha09'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta03'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta03'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0-rc01'
implementation 'androidx.preference:preference:1.1.0-rc01'
implementation 'androidx.core:core:1.2.0-alpha03'

Напоминание о том, что код Googles далеко не без ошибок и хорошо протестирован, и что кто-то никогда не должен обновлять версии легкомысленно.

Ответ 7

/**
 * 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)
}

Ответ 8

Мне удалось воспроизвести сбой 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"
}

Добавление appcompat-resources не решило проблему.

Возможно, в будущем появится версия, но я хотел бы упомянуть, что, похоже, существует дополнительная библиотека ресурсов, которая должна решить эту проблему. Поэтому, пытаясь исправить это с помощью новой версии appcompat, добавьте библиотеку appcompat-resources с той же версией.

Возвращение к androidx.appcompat:appcompat:1.0.2 решило проблему как обходной путь.

Ответ 9

Если вы не полагаетесь на переключение тем DayNight (или другие события UiMode), вы можете добавить android:configChanges="uiMode" в манифест активности веб-просмотра, чтобы AppCompatDelegate не обновлял конфигурацию ресурсов и, таким образом, не нарушал инфляцию веб-просмотра. Обнаружил этот обходной путь, изучив исходный код изменений 1.1.0-rc01 в 1.1.0.

Понижение до 1.1.0-rc01 также должно работать.