WebView的loadUrl("javascript:...")无效

3

我正在使用Android的WebView进行开发:我有一段示例文本“asdf”,当用户点击一个按钮(红色、绿色或蓝色)时,它应该变色。为了让事情变得更加复杂,WebView首先告诉Java代码触发颜色变化,然后从Java内部改变WebView:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final WebView myWebView = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }

        final WebAppInterface webAppInterface = new WebAppInterface(this, myWebView);
        myWebView.addJavascriptInterface(webAppInterface, "Android");
        myWebView.loadUrl("file:///android_asset/index.html");
    }
}

这是界面:
public class WebAppInterface {

    Context context;
    WebView webView;

    WebAppInterface(Context context, WebView webView) {
        this.context = context;
        this.webView = webView;
    }

    @JavascriptInterface
    public void dye(String color) {
        switch (color) {
            case "red":
                webView.loadUrl("javascript:dyeRed()");
                break;
            case "green":
                webView.loadUrl("javascript:dyeGreen()");
                break;
            case "blue":
                webView.loadUrl("javascript:dyeBlue()");
                break;
        }
    }
}

在我的html文件中有3个像这样的按钮:

<button onClick="callDyeRed()">
    RED
</button> 

我有一个成功加载的 JavaScript 文件,在其中包含以下类似函数:

function callDyeRed() {
  Android.dye("red");
}
function dyeRed() {
  document.getElementsByTagName('body')[0].style.color = 'red';
}

当我点击按钮时,我发现在WebAppInterface内部执行了webView.loadUrl("javascript:dyeRed()")这一行。因此,js->Java通信有效。然而,反过来就不行:之后不会执行Javascript代码。
我在这里错过了什么?
如果我从WebViewClient内部更改颜色,则通信有效:
myWebView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView webView, String url) {
        webView.loadUrl("javascript:dyeGreen()");
    } 
}); 
1个回答

0

绑定到JavaScript的对象在另一个线程('JavaBridge')中运行,而不是它构建的线程('Looper')中运行。 所有WebView方法必须在同一线程上调用。因此,您不能在新创建的线程中调用loadUrl方法。

可能的解决方法:

Webappinterface.java

class WebAppInterface {  

    Context context;
    WebView webView;

    WebAppInterface(Context context, WebView webView) {
        this.context = context;
        this.webView = webView;
    }

    @JavascriptInterface
    public String dye(String color) {
        switch (color) {
            case "red":
                return "dyeRed";
            case "green":
                return "dyeGreen";
            case "blue":
                return "dyeBlue";
            default:
                return "alert";

        }
    }
}

script.js

function callDyeRed() {
  window[Android.dye("red")]();
}
function dyeRed() {
  document.getElementsByTagName('body')[0].style.backgroundColor = 'red';
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接