0

I am calling JavascriptInterface method from webview to call javascript methods. The problem is method returns value before getting result value. So how can I make return statement wait till javascript method is executed from ui thread.

JavascriptInterface

public class CordovaJSInterface {
        Context cxt;
        String returnValueFromJS="";

        CordovaJSInterface(Context cxt){
            this.cxt = cxt;
        }
        public void setReturnValueFromJS(String valueFromJS){
            this.returnValueFromJS = valueFromJS;
        }
        @JavascriptInterface
        public String performClick()
          {

            /*MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mainView.loadUrl("javascript:" + "getLocation()" + ";");
                }

            });*/
            mainView.post(new Runnable() {
                @Override
                public void run() {
                    mainView.loadUrl("javascript:" + "getLocation()" + ";");
                }
            });
            /**PROBLEM : Method returns variable returnValueFromJS 
             * before it is updated by  getLocation() javascript method..
             **/

            return returnValueFromJS;
    }

So I want performClick() to let ui thread complete first and then return value.

Nish
  • 1
  • 1
  • 4
  • 14

2 Answers2

0

First Create an interface :

interface CallBack {
    void click(String returnValueFromJS);
}

Suppose this is the activity, implement interface you created here :

public class FirstClass extends Activity implements CallBack {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView();
    //calling cordovainterface
    new CordovaJSInterface(this).performClick(); // now control goes to perform click of cordovaJSInterface
    //cut remaining code from here and paste it in click method
}

@Override
public void click(String returnValueFromJS) {
    //code after calling cordavajsinterface should be here
    }
}

And this is cordovaJSinterface :

public class CordovaJSInterface {
Context cxt;
String returnValueFromJS = "";

CordovaJSInterface(Context cxt) {
    this.cxt = cxt;
}

public void setReturnValueFromJS(String valueFromJS) {
    this.returnValueFromJS = valueFromJS;
}

@JavascriptInterface
public void performClick() {

        /*MainActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mainView.loadUrl("javascript:" + "getLocation()" + ";");
            }

        });*/
    mainView.post(new Runnable() {
        @Override
        public void run() {
            mainView.loadUrl("javascript:" + "getLocation()" + ";");
            ctx.click(returnValueFromJS);
        }
    });
    /**PROBLEM : Method returns variable returnValueFromJS
     * before it is updated by  getLocation() javascript method..
     **/

    }
}

So when you call ctx.click(returnValueFromJS);, The control will go to click method of your activity. There do the rest whatever you want.

Akshay Bhat 'AB'
  • 2,690
  • 3
  • 20
  • 32
0

You can perhaps achieve this using Thread.join method but then you have to rely on the scheduling methodology of your underlying OS and expect it to be really fair, which it is most of the time.

However, it's not really seemed the right way to go to me (I mean waiting for UI thread). UI thread is greedy. I don't know perhaps you can increase the priority of the current js thread so it gets more CPU slices.

stdout
  • 2,471
  • 2
  • 31
  • 40