evgenyneu / js-evaluator-for-android

A library for running JavaScript in Android apps.
MIT License
485 stars 84 forks source link

Android Synchronous Callback JsEvaluator #23

Closed deepthi12 closed 8 years ago

deepthi12 commented 8 years ago

Hi , I need to execute some java script in android and based on the result i need to do some validations. But here the callback is asynchronous request and my execution does not stop till i get the result form call back . Can any one please help me to do synchronous call back that is to wait till i get the response from the call back.

evgenyneu commented 8 years ago

Hi, thanks for this feature request. I know other person wanted to evaluate JavaScript synchronously as well. It looks like this feature can be useful and I am currently implementing it.

evgenyneu commented 8 years ago

After spending 10 hours on creating a synchronous solution I give up. It proved to be harder than I though. Here are the reasons why it is tricky:

  1. The library uses a WebView to evaluate the JavaScript. It calls a web view's method loadUrl and it is required to call this method in UI thread.
  2. Web view then evaluates the JavaScript asynchronously.
  3. When web view finishes evaluating JavaScript it executes a callback method on JavaScriptInterface object and passes back the result to our library. This method is executed in the background thread.
  4. In the ideal world what we could do is to create a CountDownLatch object, call evaluate method and then call await to wait until the latch object is released when the result callback is called. The following code was proposed by @tom91136.
final CountDownLatch latch = new CountDownLatch(1);
final MutableObject<String> result = new MutableObject<>();
handler.post(new Runnable() {
    @Override
    public void run() {
        webView.evaluateJavascript(js, new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                result.setValue(value);
                latch.countDown();
            }
        });
    }
});
latch.await();
result.getValue();

Unfortunately this CountDownLatch approach works only till around Android 5.0. On new Android releases the result callback is never called. It looks like the newer Android needs UI thread unblocked in order to evaluate JavaScript.

I have created the branch called sync where I have done this work. The updated API is documented in the README of the sync branch.

evgenyneu commented 8 years ago

Closing this issue for the lack of solution, feel free to reopen if anyone has a solution to this.