代码之家  ›  专栏  ›  技术社区  ›  Dennis Hui

为什么带有HTML select标记的Android OS 8 WebVew会使应用程序崩溃

  •  17
  • Dennis Hui  · 技术社区  · 7 年前

    WebView 在Android OS 8上运行。我创建了一个带有 <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)
    

    Trying to open SELECT tag in Android WebView crashes the application

    2018年1月9日更新:

    2018年3月23日更新:

    我在这篇文章中找到了以下评论:

    必须使用活动上下文创建Webview,因为AlertDialog实例需要活动上下文。"

    我认为这是Android中的一个bug,可能没有正确处理片段的上下文。

    2018年4月17日更新:

    正如kenyee所指出的,从这里 https://issuetracker.google.com/issues/77246450 谷歌表示

    2018年11月29日编辑 似乎这个问题困扰了很多人。

    • 更新编译sdk和受支持的库版本对某些人有效。
    9 回复  |  直到 6 年前
        1
  •  3
  •   Steven Zhang    7 年前

    我在Android 8.0上也有同样的问题。 最后我解决了它。

        2
  •  3
  •   Arash Tadayon    6 年前

    如果有人仍然有这个问题,我发现甚至不是我的代码在对Resources类进行子类化,而是我正在使用的Google support library版本。更新了support library版本,效果非常好!

        3
  •  3
  •   Daniel Wilson    5 年前

    在AndroidX land(仅限于最低编译SDK版本28)中,我在带有弹出微调器的棉花糖模拟器上也遇到了这个问题。我不去任何地方接近资源,所以这仍然是一个平台问题与一个支持库。

    val webView = WebView(ContextThemeWrapper(activity, R.style.Theme_AppCompat_Light))
    binding.webViewContainer.addView(webView)
    

    我不理解wtf在这里发生了什么,但现在它起作用了。祝大家好运!

    编辑 我对此进行了更多的研究,发现了对我造成问题的依赖性。材质组件库的一个特定版本实际上在网络视图(准确地说是1.1.0-alpha06)中引入了这一点。 I have asked a question on it here

        4
  •  2
  •   kenyee    6 年前
        5
  •  1
  •   Akhil    6 年前

    我翻阅了事故日志。虽然这个答案不能解决你的问题,但你可能会得到一些有用的见解

        6
  •  1
  •   Geoff    6 年前

    实际上在不久前找到了一个解决方法,允许我们继续子类化 Resources 并且不会破坏我们的网络视图。需要注意的是,我们不能让我们的WebView看到我们的资源子类或与之交互,我们必须创建WebView程序。第一步是在Resources子类中公开方法,以将原始资源拉出。

    CustomResourcesWrapper 和我们的 ContextWrapper CustomContextWrapper .

    首先,我们更新 CustomResourcesWrapper 资源 对象

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

    我们还假设 看起来像这样。。。

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

    当需要创建Web视图时,是否确保 Context WebView webView = new WebView(unwrapCustomContext(context)) . 我不是百分之百确定为什么,但是 ContextThemeWrapper

        7
  •  0
  •   Dennis Hui    6 年前

    经过一些调查,我只在OS8上的WebView内部片段中解决了这个问题。我的解决方法是对特定流使用活动而不是片段。在我看来,这似乎是Android的一个片段缺陷。

        8
  •  0
  •   Aleksandr Gorshkov    6 年前

    ContextWrapper 在你的 Activity attachBaseContext 方法检查此方法并使用 super.attachBaseContext(newBase)

        9
  •  -3
  •   Pradeep Kumar    6 年前

    String.valueOf(value) 在Textview中设置值。