12

在 的子类中WebView,我曾经在重写的方法中有这一行getTitle()

String title = super.getTitle();

它在所有版本的Android中运行良好,直到我在Android 4.1手机上测试我的应用程序,这在该行上给了我这个警告super.getTitle()

12-20 21:38:27.467:W/webview_proxy(2537):java.lang.Throwable:警告:在线程“WebViewCoreThread”上调用了 WebView 方法。 所有 WebView 方法都必须在 UI 线程上调用。WebView 的未来版本可能不支持在其他线程上使用。

因此,我正在考虑通过通过以下方式来解决这项新法令runOnUiThread()

Activity a = this.getActivity();
a.runOnUiThread(new Runnable() {
    public void run() { 
    String title = super.getTitle();
    }
});

但是这段代码甚至不会编译,因为super不再引用WebView,而是引用Activity.

知道如何super.getTitle()从 UI 线程中获取信息吗?(具有上述约束,在 的getTitle()子类中WebView

4

4 回答 4

6

摩根的回答虽然可以修复编译错误,但并不是真正解决这个问题。

首先,它不会改变对getTitle()不同线程的调用。那个潜在的问题是为什么 Android 在运行时给你错误。

你在评论中说

情况是我在 WebViewClient.onPageFinished() 中调用它,而它恰好不在 UI 线程上。

可能是个问题。如果您从 UI 线程启动 Web 请求,那么onPageFinished()肯定应该在 UI 线程上回调。您能解释一下您是如何启动网络请求的,以及为什么要这样做吗?绝大多数情况下,您不应该onPageFinished()在后台看到呼叫,因此您可能在其他地方遇到问题。

(注意:如果您认为需要WebView.loadUrl()在后台调用以避免阻塞 UI,请参阅有关该问题的其他答案

如果你真的认为你需要在后台启动 web 请求,并且你看到onPageFinished()在后台调用,你需要小心getTitle()在 UI 线程上调用。

此外,如果您从onPageFinished()方法中调用它,则无需使用如下语法:

String title = MyWebView.this.getTitle();

在该方法中,您将获得 Web 视图的实例,因此只需直接使用它:

public void onPageFinished (WebView view, String url) {
    String title = view.getTitle();
}

但是,正如我所说,这并不能解决线程问题。您需要向我们展示您为什么尝试在该方法中使用页面标题,但安全使用它的一种方法是这样的:

public void onPageFinished (final WebView view, String url) {
   view.post(new Runnable() {
      public void run() { 
         String title = view.getTitle();
         // do something with title that affects the UI here
      }
   });     
}

请注意,我需要在上面的代码中 制作view参数。final

于 2013-01-01T22:46:10.333 回答
5

我没有直接回答您的问题,但是当我遇到类似问题时,我可以建议一种对我有用的解决方法:找到调用调用方法的方法并通过runOnUiThread()String title = super.getTitle();运行

HTH。

于 2012-12-24T00:01:14.263 回答
2

直接的解决方案是这样做

String title = MyWebView.this.getTitle();

代替

String title = super.getTitle();

话虽如此,了解更多关于您调用它的情况会很有趣(即,为什么您在后台调用它)。我之所以问,是因为我不确定即使在您进行了我提到的代码更改之后,您的方法是否会达到您想要的效果。

于 2013-01-01T18:07:59.257 回答
0

要消除此警告,请执行以下操作:

  Handler handler =new Handler();
    handler.post(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            String URL = "http://www.superlinux.net";

            //Of course the object "webview" is a WebView. 
            //it's better to define it a global variable
            webview.loadUrl(URL);
        }
    });

因此,使用这种方式,因为 webview 是 UI 元素,所以使用 Handler 对象。处理程序是与创建任何 UI 元素分开运行的某种线程。

于 2013-03-31T09:33:33.417 回答