簡體   English   中英

從Android WebView回調/接口執行任意JavaScript

[英]Executing arbitrary javascript from Android WebView callback/interface

我已經使用Android的WebView設置了一個非常簡單的javascript實現:

index.html

<!DOCTYPE html>
<html>
  <head>
  <title></title>
    <script type="text/javascript" charset="utf-8" src="Test.js"></script>
  </head>
</html>

MyJavaScript.java

public class MyJavaScript 
{
    public MyJavaScript()
    {
        // create the WebView
        mWebView = new WebView(mContext);

        // enable javaScript
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        // add javaScript interface
        mWebView.addJavascriptInterface(new JavaScriptTest, "_test");

        // load our dummy page
        mWebView.loadUrl("file:///android_asset/javascript/index.html");
    }

    public void exec(String script)
    {
        mWebView.loadUrl("javascript:" + script);
    }
}

Test.js

function Test()
{
};

Test.prototype.foo = function()
{
    window._test.foo();
};

Test.prototype.bar = function()
{
    window._test.bar();
};

var test = new Test();

JavaScriptTest.java

public class JavaScriptTest
{
    public void foo()
    {
        Log.d("Test", "foo");
    }

    public void bar()
    {
        Log.d("Test", "bar");
    }
}

當呼叫者撥打類似的內容時:

MyJavaScript.exec("foo();");

執行最終會傳播到JavaScriptTest.foo()。 該執行在WebView的工作線程中。

我想在JavaScriptTest.foo()中做的事情類似於eval(“ bar();”);。 我基本上想從Java回調/接口同步執行更多的javascript。 也就是說,我希望在返回JavaScriptTest.foo()之前完全執行javascript bar()方法。 我不知道該怎么做。

如果備份一層,則調用bar()很簡單; 來自Test.js中的foo方法。 但是,這並不能真正滿足我的需求。 我需要能夠執行JavaScriptTest.foo()中的JavaScriptTest.foo()發現的任意javascript。

而且因為JavaScripTest.foo()在WebView的工作線程中執行,所以將JavaScriptTest.foo()發現的任意javascript傳遞給WebView.loadUrl(...)都不起作用,因為您需要從UI線程調用該API。

理想情況下,在WebView的工作線程中執行的Java回調/接口存根中,將有一種方法可以執行一些任意javascript。

我可能可以通過將任意javascript傳遞回Test.js中的foo()來解決該問題,但這將是比我的首選更為通用和丑陋的解決方案。 如果我的第一選擇不存在,那么我沒有選擇。

由於WebView的線程要求,恐怕您無法實現所需的功能。 從后台線程在Java中開始新的javascript執行的唯一方法是將任務發回到UI線程,但這會破壞您的同步需求。

我認為您唯一的選擇是讓Java對象將String返回給您的JavaScript,然后進行評估(如您所建議的那樣,我認為)。

您可以修改JavaScriptTest接口以返回要評估的javascript。

public class JavaScriptTest
{
    public String foo()
    {
        return "bar();"
    }

    public void bar()
    {
        Log.d("Test", "bar");
    }
}

然后在您的JavaScript中:

function Test()
{
};

Test.prototype.foo = function()
{
    eval(window._test.foo());
};

Test.prototype.bar = function()
{
    window._test.bar();
};

var test = new Test();

返回之前不會對bar()求值,但是之后可以立即執行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM