【问题标题】:Javascript calling Android methods in WebViewJavascript 在 WebView 中调用 Android 方法
【发布时间】:2015-07-09 19:33:03
【问题描述】:

我在 WebView 中运行了一些 javascript。在这个 Javascript 代码中有一个返回布尔值的函数。我想检查这个函数的返回值,并取决于它是否隐藏我的android代码中的视图。我试了一天还是不行。有人知道我的错误在哪里吗?这是我的代码:

public class MyActivity extends Activity {
    private static final String JS_INTERFACE  = "Android";
    ....

    webView.getSettings().setJavaScriptEnabled(true);
    webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
    webView.loadUrl(getUrl(this.getResources().getString(R.string.host)));
    webView.addJavascriptInterface(new WebViewJavaScriptInterface(this), JS_INTERFACE);
    webView.setWebViewClient(new WebViewClient(progressBar, this, tvError));
    webView.setWebChromeClient(new WebChromeClient(progressBar));

    webView.loadUrl("javascript:window.Android.showAdBanner(showSdkAd())");
}

public class WebViewJavaScriptInterface
{
    ....
    @JavascriptInterface
    public void showAdBanner(String jsResult) {
        if (jsResult == "true") {
            ((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
        } else {
            ((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
        }
   }
}

【问题讨论】:

  • showSdkAd() 是什么?
  • 这是一个javascript函数,它返回一个布尔值来判断视图是否必须隐藏
  • if (jsResult == "true") 应该是 if (jsResult == true)
  • 你是对的,但我刚刚测试过它并不起作用:(

标签: javascript android webview


【解决方案1】:

if (jsResult == "true") if 语句的两种情况下,您都将可见性设置为View.GONE

我认为js中的window是不需要的,所以

webView.loadUrl("javascript:window.Android.showAdBanner(showSdkAd())");

应该是

webView.loadUrl("javascript:Android.showAdBanner(showSdkAd())");

此外,javascript 回调将在后台线程中执行,因此在执行 Ui 操作之前,您需要移动到主线程(将可运行对象发布到视图、runOnUiThread、使用处理程序等)。

如果你有一个视图的引用,你可以这样做:

@JavascriptInterface
public void showAdBanner(String jsResult) {
    viewReference.post(new Runnable() {
        public void run() {
            if (jsResult == "true") {
                 ((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
            } else {
                 ((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
           }
     }
}

由于您有对活动的引用,您可以将viewReference.post 替换为((Activity) context).runOnUiThread

如果你在主线程上初始化一个 Handler,它将绑定到主线程。作为 Activity 的一个字段,您可以:

private Handler mHandler = new Handler();

然后将viewReference.post 替换为mHandler.post 您还可以制作一个实现handleMessage(Message msg) 的自定义处理程序,然后您可以只向它发送一条空消息。但是,您应该阅读https://techblog.badoo.com/blog/2014/08/28/android-handler-memory-leaks/ 以避免内存问题。

【讨论】:

  • 是的,你是对的,但这是因为在 xml 中是可见的,它只是为了测试,无论如何都要改变可见性才能知道回调有效。
  • 啊,我明白了,我以为你期待它会被显示出来……更新了我的答案
  • 我明白你的意思,但你能举个例子吗?我该怎么做?我必须创建处理程序或其他什么?
  • 非常感谢!!!!它就像一个魅力!我看过很多教程,但你是第一个提到后台线程的人:))
猜你喜欢
  • 1970-01-01
  • 2016-05-07
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 2011-05-18
  • 1970-01-01
相关资源
最近更新 更多