【问题标题】:Trying to open SELECT tag in Android WebView crashes the application尝试在 Android WebView 中打开 SELECT 标记会使应用程序崩溃
【发布时间】:2012-02-09 14:58:25
【问题描述】:

大约一年前有人问过similar question,但还没有完全解决,但无论如何我还是要试试运气,也许有人知道这一点。

我有一个在 WebView 中运行几个 HTML 页面的应用程序。一切看起来都不错并且工作正常,直到您尝试打开 SELECT 标记 - 繁荣,应用程序崩溃。 这是一个跟踪堆栈,如果有帮助的话:

线程 [ main](暂停(异常 WindowManager$BadTokenException)) AlertDialog(Dialog).show() 行:247
WebView$InvokeListBox.run() 行:7841
WebView$PrivateHandler(Handler).handleCallback(Message) 行:587
WebView$PrivateHandler(Handler).dispatchMessage(Message) 行:92
Looper.loop() 行:130 ActivityThread.main(String[]) 行:3859
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) 行:不可用 [本机方法]
Method.invoke(Object, Object...) 行:507
ZygoteInit$MethodAndArgsCaller.run() 行:840
ZygoteInit.main(String[]) 行:598 NativeStart.main(String[]) 行:不可用 [本机方法]

(AlertDialog 与打开选择框有什么关系超出了我的理解。不,没有与打开警报的 SELECT 关联的脚本)。

现在,这是最好的部分。我正在 2 台设备上测试该应用程序,即带有 OS 2.3.3 的三星 Galaxy S2 和带有 OS 2.3.5 的摩托罗拉 RAZR XT910。在三星上,一切都很好。然而,在 RAZR 上,会发生上述情况。

这些页面包含大量 CSS 和 JavaScript,但即使删除所有内容也会崩溃。事实上,带有单个 SELECT 控件的空 HTML 仍然会崩溃。 一年前的问题中提到的一些我确实尝试过的事情:

  • 从 HTML 中删除所有绝对和固定定位元素(实际上我删除了整个 CSS 只是为了看看它是否有任何效果 - 它没有)。
  • 确保 SELECT 是按规定编写的,没有虚假属性/标签。

没有任何帮助。

有人知道是什么原因造成的吗?

【问题讨论】:

  • 在 Android 中,下拉菜单不会“下拉”(至少在 ICS 之前),它们会在 AlertDialog 内的列表中显示选项,这就是它的来源。唉,我不知道为什么会出现这个问题。
  • 您应该发布您的 HTML(或示例)以查看是否有人能发现可能导致崩溃的内容。您尝试过更简单的 SELECT 吗?
  • 看起来很简单,一个WebView需要简单多少的控件才能起作用?我的意思是,同一个 WebView 处理了相当繁重的 CSS 和 JS 动画等等,一切都很好。
  • 是的,这看起来很简单。老实说,我期待奇怪的字符或类似的东西:)。这是否在 webview 之外工作,例如在浏览器应用中?
  • 无处不在,除了 RAZR 上该死的 WebView。

标签: android android-webview html-select


【解决方案1】:

实际上你所做的是你已经将 Application Context 传递给了 webview。 SELECT 标记基本上使用 Android 的原生 AlertDialog 显示其选项,这需要 Activity Context

要解决此问题,您可以通过布局(XML)文件传递活动上下文,如下所示。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    tools:context="com.myApp.Activities.WebViewActivity">

    <WebView
            tools:context="com.myApp.Activities.WebViewActivity"
            android:layout_width="match_parent"
            android:id="@+id/webView"
            android:layout_height="match_parent"/>

</LinearLayout>

tools:context="com.myApp.Activities.WebViewActivity"

【讨论】:

  • 六年前你在哪里? :)
  • 我一直认为 tools:attr 只适用于 IDE
  • 有人确认了吗?我也“知道”工具仅适用于 IDE....
  • tools:context 根本不是这样做的。
【解决方案2】:

它崩溃是因为您将ApplicationContext 提供给了网络视图。 单击 SELECT 标记时,Android 在内部使用本机 AlertDialog 显示其选项。
必须使用 Activity 上下文创建 Webview,因为 AlertDialog 实例需要 Activity 上下文。

【讨论】:

    【解决方案3】:

    就我而言,我使用的是 androidx,我所做的只是将所有 gradle 实现更新到最新版本。根据 Playstore 指南,我根据 2020 年 11 月以后的当前最低版本将我的 compileSDK 版本更改为 29。对我来说效果很好。

    【讨论】:

      【解决方案4】:

      在网上浏览了一个多月后,我放弃了所有 SELECT 并将所有 SELECT 中继到本机代码。

      用看起来像 SELECT 的东西替换 SELECT,绑定在 JavascriptInterface 上启动方法的单击处理程序并将 SELECTs 选项值传递给它,让该方法打开带有 RadioGroupDialog,填充组RadioButtons 代表选项。选中后,解析索引并将其传递回 JavaScript(启动进程的 SELECT 实例应首先保存在某个 var 中)。

      这很丑陋,但遗憾的是似乎没有其他方法起作用。

      【讨论】:

      • 我希望。这是很久以前的事了,代码是我不再工作的公司的专有代码。
      • 我能理解这么多年之后,垃圾还在发生吗?!
      • 是的,5.1.1 发生在我身上
      【解决方案5】:

      游戏迟到了,但是我已经阅读了半个工作日,并尝试了几个工作日的不同解决方案,并且一遍又一遍地回到这个线程。我有一个内部带有 Webview 的片段,而 Oreo (28) 之前的 android 版本在选择 HTML 中的选择时崩溃了,而 28+ 则忽略了它。

      这就是 DiffyIgor_K 所说的(尽管 Diffy 的解决方案不起作用):这是错误的上下文。让我解决它的是this thread。我将复制粘贴下面的答案:

      Manish Sharma 非常感谢这个答案。

      要将新的上下文传递给 webview,您可以创建一个方法来初始化 webview,传递 Context 的参数,如下所示:

      public static Webview initializeWebView(Context context)
      {
      
        myWebView = new WebView();
        return myWebView;
      
      }
      

      然后你可以在任何你想要的地方调用这个方法并且 无论你什么时候想要。您可以如下所示调用它:

      myWebView = initializeWebView(YourActivityName.this);
      //this way whatever Context you will pass your webview will be initialized that way
      //for example you can also pass getApplicationContext() as an Argument
      myWebView = initializeWebView(getApplicationContext());
      //or
      myWebView = initializeWebView(customContext);
      

      这个 customContext 可以是任何继承自其他上下文的上下文 您想使用的上下文。

      【讨论】:

        猜你喜欢
        • 2018-03-12
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 2014-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-08
        相关资源
        最近更新 更多