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 также должно работать.