如何从UI线程WebView.getTitle()?

时间:2012-12-21 02:58:07

标签: android android-webview

WebView的子类中,我曾经在getTitle()的重写方法中使用此行:

String title = super.getTitle();

Android 的所有版本中都运行良好,直到我在 Android 4.1 手机上测试我的应用,这给了我{{1}的警告行:

  

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

所以,我正在考虑通过super.getTitle()传递这个新法令:

runOnUiThread()

但是这段代码甚至不会编译,因为Activity a = this.getActivity(); a.runOnUiThread(new Runnable() { public void run() { String title = super.getTitle(); } }); 不再引用super,而是引用WebView

知道如何从UI线程中Activity如何? (具有上述约束,在super.getTitle()

的子类的getTitle()

4 个答案:

答案 0 :(得分:6)

Morgan's answer虽然它可以解决编译错误,但实际上并不能解决这个问题。

首先,它不会将对getTitle()的调用更改为其他线程。这个潜在的问题是Android在运行时为您提供错误的原因。

你在评论中说

  

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

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

(注意:如果您认为需要在后台调用WebView.loadUrl()以避免阻止用户界面,请see this other answer on that issue

如果您确实认为需要在后台启动网络请求,并且在后台看到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

答案 1 :(得分:5)

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

HTH。

答案 2 :(得分:2)

直接解决方案就是这样做

String title = MyWebView.this.getTitle();

而不是

String title = super.getTitle();

话虽如此,了解更多关于你所谓的情况(即,你为什么在后台调用它)会很有趣。我问,因为我不确定即使你改变了我提到的代码,你的方法也会做你想要的。

答案 3 :(得分: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元素分开运行。