Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android-JsBridge通行机制总结 #30

Open
jeffrey1995 opened this issue Feb 7, 2018 · 0 comments
Open

Android-JsBridge通行机制总结 #30

jeffrey1995 opened this issue Feb 7, 2018 · 0 comments

Comments

@jeffrey1995
Copy link
Owner

前言

最近在研究JsBridge的运行机制,在学习这个框架之前,首先需要了解H5与原生之前的通信方式。下面以Android平台为例:

Js调用原生(Java)

总的来说有四种方式:

1.JavascriptInterface

2.WebViewClient.shouldOverriderUrlLoading()

3.WebViewClient.onConsoleMessage()

4.WebChromeClient.onJsPrompt()

1.1 JavascriptInterface

这个是Android提供的Js与Native通信的官方解决方案。

public class JavascriptInterface {

    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
    }
}

首先定义一个Java类,其中提供一个方法showToast(加上JavascriptInterface注释),然后调用WebView.addJavascriptInterface(new JavascriptInterface(),"javascriptInterface"),之后再js代码中就直接通过“JavascriptInterface”直接调用该原生方法。

但是这个官方提供的解决方案在Android4.2之前存在严重的安全漏洞。在Android4.2之后,加入了@JavascriptInterface才得到解决。所以考虑到兼容低版本的系统,JavascriptInterface并不适合。

2.1 WebViewClient.shouldOverriderUrlLoading()

该方法的实现原理:拦截WebView的跳转Url,若满足事先约定好的格式,去解析该url并执行相应的原生逻辑,否则不进行拦截。原生代码如下:

public class CustomWebViewClient extends WebViewClient {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (isJsBridgeUrl(url)) {
            // JSbridge的处理逻辑
            return true;
        }
        return super.shouldOverrideUrlLoading(view, url);
    }
}

3.1 WebViewClient.onConsoleMessage()

该接口是Android提供给Js调试在Native代码里打印日志信息的API,利用该接口可以实现js与原生的通信。在js中的调用代码如下:

console.log('log message that is going to native code')

在Native端的回调如下所示,可以对获取到的日志内容进行解析然后执行相应的方法。

public class CustomWebChromeClient extends WebChromeClient {

    @Override
    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
        super.onConsoleMessage(consoleMessage);
        String msg = consoleMessage.message();//JavaScript输入的Log内容
    }
}

4.1 WebChromeClient.onJsPrompt()

WebChromeClient有三个方法,WebChromeClient.onJsPrompt()、WebChromeClient.onJsAlert()和WebChromeClient.onJsConfirm()。这三个Js给Native端的回调接口,作用分别是展示提示信息、展示警告信息和展示确认信息。alert和confirm在Js的使用率很好,所以通常选用的解决方案是onJsPrompt()。
Js中的调用代码如下:

window.prompt(message, value)

Native端的回调如下所示,其中的message参数是js端传入的message的值。

public class CustomWebChromeClient extends WebChromeClient {

    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        // 处理JS 的调用逻辑
        result.confirm();
        return true;
    }
}

Java调用Js

利用webView的loadUrl方法

webView.loadUrl(String.format("javascript:WebViewJavascriptBridge._handleMessageFromNative(%s)", data));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant