JsBridge

Project Url: hjhrq1991/JsBridge
Introduction: 基于 github.com/lzyzsd/JsBridge 优化改进而来的 JsBridge
More: Author   ReportBugs   OfficialWebsite   
Tags:


JsBridge 库现已迁移至 Jitpack,具体使用如下: 1.工程根 build.gradle 添加 jitpack

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

2.模块 build.gradle 添加依赖

dependencies {
    implementation 'com.github.hjhrq1991:JsBridge:1.1.1'
}


本项目共有两个部分: 1.基于系统的 JsBridge; 2.基于 Tbs X5 内核的 JsBridge;

基于https://github.com/lzyzsd/JsBridge 优化改进而来的 Android JsBridge

优化

1.支持自定义桥名;
2.修复 web 页未渲染即进行跳转导致 Js 桥初始化失败的问题;

使用

添加 maven 依赖

<dependency>
  <groupId>com.hjhrq1991.library</groupId>
  <artifactId>jsbridge</artifactId>
  <version>1.1.0</version>
  <type>pom</type>
</dependency>

添加 gradle 依赖

compile 'com.hjhrq1991.library:jsbridge:1.1.0'

在你的布局上添加 BridgeWebView

<com.hjhrq1991.library.BridgeWebView
 android:id="@+id/webView"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

使用默认桥名或自定义桥名

//description:如需使用自定义桥名,调用以下方法即可,
// 传空或不调用 setCustom 方法即使用默认桥名。
// 默认桥名:WebViewJavascriptBridge
webView.setCustom("TestJavascriptBridge");

Android 上使用方法

注册一个 handler 方法供 Js 调用

webView.registerHandler("initSignNetPay", new BridgeHandler() {
   @Override
   public void handler(String data, CallBackFunction function) {
      Log.i(TAG, "回传结果:" + data);
      Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
   }
});

Java 里调用 Js 里的 handler 方法

webView.callHandler("click1", "success", new CallBackFunction() {
   @Override
   public void onCallBack(String data) {
      Log.i(TAG, "回传结果:" + data);
      Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
   }
});

使用默认 handler 方法来进行交互

webView.setDefaultHandler(new DefaultHandler());
window.WebViewJavascriptBridge.send(
   data, function(responseData) {
      document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData
   }
);

JavaScript 上使用方法

构建桥连接

var default_data = {
   error: "1"
};

var connectMerchantJSBridge = function (callback) {
   try {
      if (window.WebViewJavascriptBridge) {
      callback(WebViewJavascriptBridge);
   } else {
      document.addEventListener("WebViewJavascriptBridgeReady", function () {
         callback(WebViewJavascriptBridge);
         }, false);
      }
   } catch (ex) { }
};

var cmbMerchantBridge = {
   initSignNet: function (payData,name) {
      if (!payData) {
         payData = default_data;
      }
      connectMerchantJSBridge(function (bridge) {
         if (typeof bridge === "undefined") {
            return;
         }
      bridge.callHandler(name, JSON.stringify(payData));
      });
   },
};
`

调用 Android 上的 handler 方法

function click1(){
   var objData = new datas();
   var payData = objData.click1;
   try {
      cmbMerchantBridge.initSignNet(payData, "initSignNetPay");
   } catch (ex) { }
}

JavaScript 里注册一个 handler 方法供 Android 调用

/*app native 调用本页面方法*/
connectMerchantJSBridge(function(bridge) {
   bridge.init(function(message, responseCallback) {

});

bridge.registerHandler("click1", function(data, responseCallback) {
   responseCallback("receive click1");
   //可以在下面执行操作
   });
})

window.cmbMerchantBridge = cmbMerchantBridge;

setWebViewClient

Js 桥的处理在 WebViewClient 里进行,因此使用 setWebViewClient()方法会导致 Js 桥失效 因此提供新的 API 方法进行回调

        webView.setBridgeWebViewClientListener(new SimpleBridgeWebViewClientListener() {

        });

当然你也可以直接 new BridgeWebViewClientListener()

        webView.setBridgeWebViewClientListener(new BridgeWebViewClientListener() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                return false;
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return false;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {

            }

            @Override
            public void onPageFinished(WebView view, String url) {

            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

            }

            @Override
            public void onLoadResource(WebView view, String url) {

            }

            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                return null;
            }

            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                return null;
            }

            @Override
            public boolean onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) {
                return false;
            }

            @Override
            public boolean onFormResubmission(WebView view, Message dontResend, Message resend) {
                return false;
            }

            @Override
            public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {

            }

            @Override
            public boolean onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                return false;
            }

            @Override
            public boolean onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
                return false;
            }

            @Override
            public boolean onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
                return false;
            }

            @Override
            public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
                return false;
            }

            @Override
            public boolean onUnhandledKeyEvent(WebView view, KeyEvent event) {
                return false;
            }

            @Override
            public void onScaleChanged(WebView view, float oldScale, float newScale) {

            }

            @Override
            public void onReceivedLoginRequest(WebView view, String realm, String account, String args) {

            }

            @Override
            public void onPageCommitVisible(WebView view, String url) {

            }

            @Override
            public boolean onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                return false;
            }

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {

            }
        });

二、TbsBridgeWebView

TbsBridgeWebView 基于 Tbs(腾讯浏览服务)X5 内核,结合 JsBridge 的自定义 WebView。

TbsBridgeWebView 使用

考虑 App 用户群的极少数没装有微信、手 Q 的情况,因此采用 TbsX5 for share。下文基于 Tbs for share 来实现。

之前写过一篇Android-使用 JsBridge 来优化 js 与本地的交互的文章,这次的 TbsBridgeWebView 同样集成了这套 JsBridge,同时使用 TbsX5 解决 web 适配问题。

添加 maven 依赖

<dependency>
<groupId>com.hjhrq1991.library.tbs</groupId>
<artifactId>tbsjsbridge</artifactId>
<version>1.0.7</version>
<type>pom</type>
</dependency>

添加 gradle 依赖

compile 'com.hjhrq1991.library.tbs:tbsjsbridge:1.0.7'

添加权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

在你的布局上添加 TbsBridgeWebView

<com.hjhrq1991.library.tbs.TbsBridgeWebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />

JsBridge 的使用请参考上面的使用方法。

重要 Tips

Tbs 替换 android.webkit 相同的类

#系统内核                                       #SDK 内核
android.webkit.ConsoleMessage                 com.tencent.smtt.export.external.interfaces.ConsoleMessage
android.webkit.CacheManager                   com.tencent.smtt.sdk.CacheManager(deprecated)
android.webkit.CookieManager                  com.tencent.smtt.sdk.CookieManager
android.webkit.CookieSyncManager              com.tencent.smtt.sdk.CookieSyncManager
android.webkit.CustomViewCallback             com.tencent.smtt.export.external.interfaces.IX5WebChromeClient.CustomViewCallback
android.webkit.DownloadListener               com.tencent.smtt.sdk.DownloadListener
android.webkit.GeolocationPermissions         com.tencent.smtt.export.external.interfaces.GeolocationPermissionsCallback
android.webkit.HttpAuthHandler                com.tencent.smtt.export.external.interfaces.HttpAuthHandler
android.webkit.JsPromptResult                 com.tencent.smtt.export.external.interfaces.JsPromptResult
android.webkit.JsResult                       com.tencent.smtt.export.external.interfaces.JsResult
android.webkit.SslErrorHandler                com.tencent.smtt.export.external.interfaces.SslErrorHandler
android.webkit.ValueCallback                  com.tencent.smtt.sdk.ValueCallback
android.webkit.WebBackForwardList             com.tencent.smtt.sdk.WebBackForwardList
android.webkit.WebChromeClient                com.tencent.smtt.sdk.WebChromeClient
android.webkit.WebHistoryItem                 com.tencent.smtt.sdk.WebHistoryItem
android.webkit.WebIconDatabase                com.tencent.smtt.sdk.WebIconDatabase
android.webkit.WebResourceResponse            com.tencent.smtt.export.external.interfaces.WebResourceResponse
android.webkit.WebSettings                    com.tencent.smtt.sdk.WebSettings
android.webkit.WebSettings.LayoutAlgorithm    com.tencent.smtt.sdk.WebSettings.LayoutAlgorithm
android.webkit.WebStorage                     com.tencent.smtt.sdk.WebStorage
android.webkit.WebView                        com.tencent.smtt.sdk.WebView
android.webkit.WebViewClient                  com.tencent.smtt.sdk.WebViewClient

com.tencent.smtt.sdk.CookieManager 和 com.tencent.smtt.sdk.CookieSyncManager 的相关接口的调用,在接入 SDK 后,需要放到创建 X5 的 WebView 之后(也就是 X5 内核加载完成)进行;否则,cookie 的相关操作只能影响系统内核。

License

This project is licensed under the terms of the MIT license.

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools