【问题标题】:Trouble with inserting JavaScript statement插入 JavaScript 语句时遇到问题
【发布时间】:2014-07-08 09:10:13
【问题描述】:

我目前正在创建一个安卓应用程序。

该应用程序的目的是将一些注入的 JavaScript 代码触发到我在我的 android 应用程序中创建的 WebView 中。我遇到的问题是已注入的操作不起作用。

您还应该知道,我正在加载的 html 页面是在本地创建的。该应用程序的目的是显示吐司消息。代码清单如下:

//uses javascript that is in the local HTML file

public class MainActivity extends Activity {
final String URL = "file:///android_asset/index.html";
private WebView myWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    WebView myWebView = (WebView) findViewById(R.id.webview);
    WebSettings webSettings = myWebView.getSettings(); 
    webSettings.setJavaScriptEnabled(true);

     myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
    String test= "test";

    String javascript ="javascript:document.addEventListener('click', function(){Android.showToast(toast)})";
   myWebView.loadUrl(javascript);
   myWebView.loadUrl(URL);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

public class WebAppInterface {
    Context mContext;

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

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
  }
}

【问题讨论】:

  • showToast方法中注入的toast变量在哪里定义?您的问题可能是在您的 javascript 回调范围内无法访问此变量。
  • show toast 的声明在底部。我知道代码有效,因为它在我从 HTML 中启动时有效。但是,我想做的是让它通过java注入并以这种方式运行。
  • 我没有要求声明showToast 方法,而是要求你传递给showToasttoast 变量的定义。我想这个变量是在你的 javascript 代码中声明和定义的,但想知道在哪里(即你可以发布你的 javascript 代码的相关部分吗?)。
  • 对不起我的错误。 toast 变量没有正确的定义。 public void showToast(String toast) 没有定义它。我知道吐司位有效,所以我认为它与实际的javascript有关。具体行是:"javascript:document.addEventListener('click', Android.showToast)";
  • @Sztucki 可以提供一个带有最终 html 输出的 jsfiddle 示例。

标签: java javascript android webview code-injection


【解决方案1】:

您的实施存在几个问题。

toast 变量可能未在您的回调范围内定义。另外,您缺少两个分号,一个在调用showToast 方法之后,另一个在addEventListener 方法的末尾,这会导致语法错误。

最后,您要在加载页面之前加载 Javascript 代码,这会使页面失效。您应该在网页完成加载后注入您的 javascript 代码,如下例所示。

我采用了您的示例并在自定义应用程序中对其进行了重写,以确保其正常工作。这是我写的:

安卓:

// Registering the JS interface
mWebView.addJavascriptInterface(new JSInterface(), "JSInterface");
// Waiting for the page to be fully loaded, and injecting the JS code
mWebView.setWebViewClient(new WebViewClient() {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        return false;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        view.loadUrl(INJECTED_CODE);
    }
});
// Load your custom url
mWebView.loadUrl(YOUR_ACTUAL_URL);

/**
 * Interface between Java and Javascript.
 */
public class JSInterface {

    @JavascriptInterface
    public void showToast(String toast) {
        Log.d("debug", "I got : " + toast);
    }
}

注入的javascript:

public static final String INJECTED_CODE = "javascript:"
        + "(function() { "
            + "document.addEventListener('click', function(){JSInterface.showToast('Hello Android !');});"
        + "})()";

【讨论】:

    【解决方案2】:

    您正试图在加载 html 页面之前调用该 JS 代码。 我猜是文档对象还没有准备好。

    更改您的事件侦听器并绑定到窗口 来自:

    String javascript ="javascript:document.addEventListener('click', function(){Android.showToast(toast)})";
    

    收件人:

    String javascript ="javascript:window.addEventListener('click', function(){Android.showToast(toast)})";
    

    你应该得到一个结果。如果不是,点击时 logcat 会吐出什么?

    编辑:刚刚看到 Halim Qarroums onPageFinished 解决方案,在您的情况下这可能是一个更好的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多