Ответ 1
Похоже, эта ошибка: https://issuetracker.google.com/issues/77246450
Не делите ресурсы на подклассы... не будет исправлено, по-видимому.
У меня есть гибридное приложение для Android Cordova, и оно вылетает, когда пользователь нажимает на раскрывающийся список в моем WebView
работающем под управлением ОС Android 8. Я создал простую страницу с <select>
и проблема воспроизводима, У меня есть обходной путь, который заключается в том, чтобы сделать свое собственное всплывающее предупреждение, чтобы выбрать, но просто интересно, происходит ли это с кем-то еще и является ли это ошибкой WebView
.
Ниже приведена простая страница с <select>
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select
Ниже мой аварийный журнал
11:04:58.643 3208-3208/com.****.****E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.****.****, PID: 3208 android.content.res.Resources$NotFoundException: Resource ID #0x0
at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:195)
at android.content.res.Resources.loadXmlResourceParser(Resources.java:2133)
at android.content.res.Resources.getLayout(Resources.java:1142)
at android.view.LayoutInflater.inflate(LayoutInflater.java:421)
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:416)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java:407)
at org.chromium.content.browser.input.SelectPopupAdapter.getView(SelectPopupAdapter.java:53)
at android.widget.AbsListView.obtainView(AbsListView.java:2372)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1408)
at android.widget.ListView.onMeasure(ListView.java:1315)
at android.view.View.measure(View.java:21998)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:21998)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:21998)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:21998)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:21998)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:21998)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:721)
at android.view.View.measure(View.java:21998)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2410)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1471)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1751)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Моя проблема не такая, как эта
При попытке открыть тег SELECT в Android WebView происходит сбой приложения
ОБНОВЛЕНИЕ 9-го января 2018 года: у меня пока нет решения, мой временный обходной путь - удалить тег и просто использовать ввод. Когда пользователь выбирает этот элемент, мы передаем событие в собственный код, чтобы открыть диалоговое окно для выбора и обновляем ввод после того, как пользователь сделал выбор.
ОБНОВЛЕНИЕ 23 марта 2018 года. После еще одного расследования я заметил, что он падает только в том случае, если WebView находится во фрагменте, но не в действии.
Я нашел ниже комментарии от этого поста:
При попытке открыть тег SELECT в Android WebView происходит сбой приложения
"При щелчке по тегу SELECT Android отображает свои параметры с помощью собственного AlertDialog. Веб-представление должно быть создано с контекстом Activity, поскольку экземпляру AlertDialog нужен контекст Activity".
Я считаю, что это ошибка в Android, возможно, неправильно обрабатывает контекст для фрагмента.
ОБНОВЛЕНИЕ 17 апреля 2018 года:
Как указал Кенье, отсюда https://issuetracker.google.com/issues/77246450, Google говорит
Вы не должны наследовать объект ресурсов - это никогда не поддерживалось и было возможно только случайно (именно поэтому теперь оно помечено как устаревшее). Фреймворк должен знать обо всех объектах ресурсов, чтобы он мог обновлять их при загрузке веб-просмотра (поскольку веб-просмотр добавляет дополнительные пути к менеджеру ресурсов).
Редактировать 29 ноября 2018 г. Кажется, эта проблема беспокоила многих людей.
Похоже, эта ошибка: https://issuetracker.google.com/issues/77246450
Не делите ресурсы на подклассы... не будет исправлено, по-видимому.
У меня такая же проблема на Android 8.0. наконец, я решаю это. Попробуйте обновить свой compileSdkVersion до 26, и обновите свой com.android.support:appcompat-v7 до 26.
Если у кого-то все еще есть эта проблема, я обнаружил, что это был даже не мой код, который подклассифицировал класс Resources, а скорее версию библиотеки поддержки Google, которую я использовал. Обновлена версия библиотеки поддержки, и она работала как шарм!
Я попал в журналы сбоев. Хотя этот ответ не решает вашу проблему, вы можете получить полезную информацию
Я не уверен, почему это происходит на Android 8.0, я не смог воспроизвести это на эмуляторе Android 8.0, хотя
После некоторого расследования я изолировал проблему с WebView внутри Fragment только на OS8. Мой обходной путь - использовать Activity вместо Fragment для этого конкретного потока. Мне кажется дефект Android во Фрагменте.
Возможно, вы используете пользовательский ContextWrapper
в своем классе Activity
. В моем случае я переопределяю метод attachBaseContext
. Проверьте этот метод и используйте super.attachBaseContext(newBase)
.
На самом деле, недавно мы нашли обходной путь для этого, который позволил нам продолжать создавать подклассы Resources
а не разрушать наши веб-представления. Предупреждение: мы не можем позволить нашему WebView видеть или взаимодействовать с подклассом наших ресурсов И мы должны создавать WebView программно. Первым шагом является предоставление метода в подклассе Resources для извлечения исходных ресурсов.
Допустим, наш подкласс ресурсов называется CustomResourcesWrapper
и наш ContextWrapper
подкласс называется CustomContextWrapper
.
Сначала мы обновляем CustomResourcesWrapper
чтобы получить доступ к исходному объекту Resources
public class CustomResourcesWrapper {
public static Resources findOriginalResources(Context context) {
if (context.getResources() instanceof CustomResourcesWrapper) {
return ((CustomResourcesWrapper) context.getResources()).getOriginalResources();
}
if (context instanceof ContextWrapper) {
return findOriginalResources(((ContextWrapper) context).getBaseContext());
}
return context.getResources();
}
private Resources getOriginalResources() {
return originalResources;
}
}
Мы также предполагаем, что CustomContextWrapper
выглядит примерно так...
public class CustomContextWrapper extends ContextWrapper {
private final Resources wrappedResources;
public CustomContextWrapper(Context base, Resources resources) {
super(base);
this.wrappedResources = resources;
}
@Override
public Resources getResources() {
return wrappedResources;
}
}
Затем мы создаем статический вспомогательный метод, чтобы "развернуть" наши пользовательские ресурсы и скрыть их
// the method name is a bit of a misnomer,
// we're actually unwrapping, then re-wrapping
public static Context unwrapCustomContext(Context wrapped) {
Resources originalResources = CustomResourcesWrapper.findOriginalResources(wrapped);
Context customUnwrappedContext = new CustomContextWrapper(wrapped, originalResources);
return new ContextThemeWrapper(customUnwrappedContext, android.support.v7.appcompat.R.style.Theme_AppCompat_Light);
}
Когда приходит время для создания WebView, убедитесь, что переданный ему Context
проходит через вышеуказанный метод, т.е. WebView webView = new WebView(unwrapCustomContext(context))
. Я не уверен на 100%, почему, но ContextThemeWrapper
является обязательной частью этого хака.
В AndroidX land (ограничено минимумом compileSDKVersion 28) я также получил эту проблему на эмуляторе Marshmallow с всплывающим спиннером. Я не подхожу к ресурсам, так что это все еще проблема платформы с одной из библиотек поддержки.
Мне удалось заставить его работать - не путем перемещения веб-просмотра в Activity (хотя я и пробовал это делать, в этом не было необходимости), - но путем добавления его программным способом в упакованном контексте и стандартной темой AppCompat:
val webView = WebView(ContextThemeWrapper(activity, R.style.Theme_AppCompat_Light))
binding.webViewContainer.addView(webView)
Я не понимаю, что здесь происходит wtf, но сейчас это работает. Удачи людям!
РЕДАКТИРОВАТЬ Я посмотрел на это намного больше и нашел зависимость, которая вызывает проблемы для меня. Определенная версия библиотеки компонентов материала фактически вызывает это в веб-обзорах (точнее, 1.1.0-alpha06). Я задал вопрос об этом здесь, с примером проекта.
Похоже, вы устанавливаете значение Integer в Textview. попробуйте использовать String.valueOf(value)
для установки значения в Textview.