【问题标题】:cannot access javascript output in android code properly无法正确访问 android 代码中的 javascript 输出
【发布时间】:2016-08-24 13:23:20
【问题描述】:

我已使用this 指南将 JavaScript 代码绑定到正常工作的 Android 代码(Toast 消息由 javascript 代码触发,并显示 javascript 代码的 double 类型输出)。我的问题是我不能在代码的其他部分使用输出。例如,正确的输出是10, 20, 30, ...,但我在另一部分代码中访问的是0, 10, 20, 30, ...。这是我代码的相关部分:

public class myFragment extends Fragment {
    int globalVar;
    .
    .
    .
    //some android code
    .
    .
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_item_show:
            loadNew();
            Toast.makeText(getActivity(), "globalVar " + String.valueOf(globalVar), Toast.LENGTH_SHORT).show();
  //after clicking menu item, I receive a double output from javascript, 
  //but first output is zero!!!
        .
    .
    .
    //some android code
    .
    .
public class WebAppInterface {
    Context mContext;

    /** Instantiate the interface and set the context */
    WebAppInterface(Context c) {
        mContext = c;
    }
    @JavascriptInterface
    public void showToast(double toast) {
        Toast.makeText(mContext, String.valueOf(toast), Toast.LENGTH_SHORT).show();
        //In this part of code, results are correct
        globalVar =  (int) (toast);
    }
}

每次我点击菜单项时,都会加载一个新页面,并且 javascript 代码会给出一个新结果。

<body onLoad="showAndroidToast();">

我认为问题源于从内部类访问变量,或者可能还有其他原因。 先感谢您。

【问题讨论】:

  • 您好,您的showAndroidToast() 方法是什么样的?由于您在 onLoad 事件中拥有它,因此每次加载页面时都会执行它。所以也许你应该在你的文档上有一个按钮和一个 onClick 事件处理程序,比如&lt;input type="button" value="Make a Toast" onClick="showAndroidToast('&lt;some-value&gt;')" /&gt;&lt;br/&gt;
  • 感谢您的回答@ishmaelMakitla。在 showAndroidToast() 中,我定义了一个双变量,然后调用 Android.showToast(myVar)。使用按钮不会进行任何更改,因为在“public void showToast(double toast)”中我收到了正确的结果。
  • 我明白了,您说您不能在代码的其他部分使用输出(双值) - 这个“代码的另一部分”在哪里,似乎有不正确的数字 0, 10, 20, 30, ...?我怀疑这是在 Menu-Item-Click 功能中,但只是为了确认,所以我可以提出一些建议......
  • @ishmaelMakitla:首先单击菜单项会导致新页面加载并触发 JS 代码,第一个输出应该是 10,我收到 10 作为 'public void showToast(double toast)' 中的第一个输出.但在“WebAppInterface”类之外的任何地方,“globalVar”为零。通过第二次单击菜单项,输出为 20,但现在 globalVar,在 'WebAppInterface' 类之外为 10。我希望现在问题会更清楚。
  • 好的,这是有道理的——问题是在菜单项单击期间,globalVar 尚未设置(0 是您未初始化的 int 的默认值)——仅当 JS 脚本执行 showAndroidToast 函数时 - 接收到 toast 的值(正确),然后分配给变量 globalVar - 因此由于这个顺序,globalVar 将始终具有先前的值(如 010 等) - 所以这是预期的行为。我将发布我建议的解决方案作为答案(评论空间有限)。

标签: javascript java android global-variables inner-classes


【解决方案1】:

//Java结束//

关于创建 Webview 活动

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JavaScriptInterface(this), "JSInterface");

之后

//Class to be injected in Web page
    public class JavaScriptInterface implements JavascriptCallback {
        Context mContext;

        /**
         * Instantiate the interface and set the context
         */
        JavaScriptInterface(Context c) {
            mContext = c;
        }

        /**
         * Show a toast from the web page
         */
        @JavascriptInterface
        public void loadComplete() {
            pd.dismiss();
        }
 // this code will use to show toast from javascript
        @JavascriptInterface
        public void showToast(String toast) {
            Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
        }
       // this code will use to call a java code from javascript with some parameters.
        @JavascriptInterface
        public void getTimeandDistance(String time, String distance) {

            disTime = "Time: " + time + " | Distance: " + distance;
            runOnUiThread(new Thread(new Runnable() {
                public void run() {
                    try {
                        someTextview.setText(disTime);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }));

        }
    }

// Java 脚本结束 //

function someFunction(data) {

        var distance = data.route.distance;

        var time = data.route.formattedTime;

         // In this way we call a java code from javascript with some parameters.

         JSInterface.getTimeandDistance(time + "", distance + "");

}

只是为了展示你可以这样做

// write anywhere in your javaScript code
JSInterface.showToast("Show Toast");

【讨论】:

  • 感谢您的回答@Hamza Mehmood。 JavascriptCallback 无法解析。
【解决方案2】:

我的建议是让您使用一些“listener”或“callback”(作为第二个参数传递给WebAppInterface),它们将在showAndroidToast 方法中得到通知。我创建了一个Gist of such a listener,只需将其添加到您的包中并更新包名称即可。 然后你更新你的内部类 (WebAppInterface) 以在其构造函数中获取第二个参数:

public class WebAppInterface {
    Context mContext;
     DummyToastListener toastListener;
    /** Instantiate the interface and set the context */
    WebAppInterface(Context c, DummyToastListener listener) {
        mContext = c;
        toastListener = listener;
    }
    @JavascriptInterface
    public void showToast(double toast) {
        Toast.makeText(mContext, String.valueOf(toast), Toast.LENGTH_SHORT).show();
        toastListener.onToastValue(toast);
    }
}

然后你更新 myFragment 类来实现 DummyToastListener 像这样:

public class myFragment extends Fragment implements DummyToastListener {

   //some where in your code, initializing the WebAppInterface
   //the second argument is also a 'this' because the fragment implements the interface
   webView.addJavascriptInterface(new WebAppInterface(this, this), "Android");
   //implementing the method of the interface DummyToastListener
   @Override
   public void onToastValue(double value){
     //got the new value from Javascript function, do whatever...
     Toast.makeText(getActivity(), String.valueOf(value), Toast.LENGTH_LONG).show();
   }

 }

使用这种方法,来自 Javascript 函数的值在 onToastValue 回调方法中将始终是新的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    相关资源
    最近更新 更多