【问题标题】:Android webview javascript interface method returns value before ui thread is finishedAndroid webview javascript接口方法在ui线程完成之前返回值
【发布时间】:2016-02-27 23:00:57
【问题描述】:

我正在从 webview 调用 JavascriptInterface 方法来调用 javascript 方法。问题是方法在获取结果值之前返回值。那么如何让 return 语句等到从 ui 线程执行 javascript 方法。

Javascript接口

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

所以我想让performClick()先让ui线程完成再返回值。

【问题讨论】:

  • 您必须为此使用界面。在mainView.loadUrl()之后调用接口。
  • @AkshayBhat 请您详细说明一下代码.. 我真的很沮丧。

标签: android multithreading webview android-runonuithread webviewrunonuithread


【解决方案1】:

首先创建一个接口:

interface CallBack {
    void click(String returnValueFromJS);
}

假设这是活动,实现你在这里创建的接口:

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
    }
}

这是cordovaJS接口:

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..
     **/

    }
}

所以当您调用ctx.click(returnValueFromJS); 时,控件将转到您活动的单击方法。剩下的随你做。

【讨论】:

    【解决方案2】:

    您也许可以使用Thread.join 方法来实现这一点,但是您必须依赖底层操作系统的调度方法并期望它真的很公平,这是大多数时候。

    但是,这似乎不是我的正确方法(我的意思是等待 UI 线程)。 UI 线程是贪婪的。我不知道您是否可以提高当前 js 线程的优先级,以便获得更多的 CPU 片。

    【讨论】:

      猜你喜欢
      • 2019-04-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-08
      • 2017-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多