2

I have some javascript running in WebView. In this Javascript code there a function which returns a boolean. I want to check the return value from this function and depends on it hide or not a view in my android code. I tried for one day and it does not work. Do someone knows where is my error? This is my code:

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);
        }
   }
}
IrApp
  • 1,823
  • 5
  • 24
  • 42

1 Answers1

1

You're setting the visibility to View.GONE in both cases of the if (jsResult == "true") if statement.

I think the window in the js is unneeded, so

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

Should be

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

Also, the javascript callback will be executed in a background thread, so you need to move to the main thread (posting a runnable to a view, runOnUiThread, using a handler etc), before performing Ui operations.

If you have a reference to a View, you can do:

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

Since, you have a reference to the activity, you can replace viewReference.post with ((Activity) context).runOnUiThread

If you initialise a Handler on the main thread, it will be bound to the main thread. As a field of the Activity, you could have:

private Handler mHandler = new Handler();

And then replace viewReference.post with mHandler.post You could also make a custom Handler that implements handleMessage(Message msg) and then you can just send it an empty message. However, you should read https://techblog.badoo.com/blog/2014/08/28/android-handler-memory-leaks/ to avoid memory issues.

FunkTheMonk
  • 10,908
  • 1
  • 31
  • 37
  • Yes, you are right, but this is because in the xml is visible, it was only for testing, its supose to change the visibity anyway to know that the call back works. – IrApp Apr 30 '15 at 08:08
  • ah, I see, thought you were expecting it to be shown.. updated my answer – FunkTheMonk Apr 30 '15 at 08:14
  • I see what you mean but could you give me an example what do I have to do? What do I have to create the handler or whatever? – IrApp Apr 30 '15 at 08:30
  • Thanks a lot of!!!! It works like a charm!!I have seen a lot of tutorials but you are the first mentioning the background thread :)) – IrApp Apr 30 '15 at 09:06