ZJsBridge imitation WeChat architecture, a complete set of native-bridge-web protocol and implementation

ZJsBridge imitation WeChat architecture, a complete set of native-bridge-web protocol and implementation

If you think the article is helpful to you, welcome , my Github .


A complete set of native-bridge-web protocol and implementation, clear and standardized development of Hybrid App github.com/hcanyz/ZJsB...

Support API v19+
Support androidx

zfjs-sdk project

What can ZJsBridge do

  • Provide complete js-sdk to the web to form the concept of sdk version
  • Provide jsapi component realization capability for native
  • Data integrity verification during interaction

What scenarios need to use ZJsBridge

  • More web and native interactions need to unify native external api
  • Native componentization, need not provide different native api modules

How to use (see demo for details)

Add dependency

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

dependencies {
    implementation 'com.github.hcanyz:ZJsBridge:1.0.0'

WebView implements IZWebView

class WebView : WebView, IZWebView {
    private val zWebHelper: ZWebHelper by lazy { ZWebHelper(this) }

    override fun getCurUrl(): String {
        return url

    override fun getCurContext(): Context {
        return context

    override fun getCurZWebHelper(): ZWebHelper {
        return zWebHelper

    override fun execJs(methodName: String, params: String?, valueCallback: ValueCallback<String>?) {
        val js: String = if (params.isNullOrBlank()) {
            String.format("%s()", methodName)
        } else {
            String.format("%s('%s')", methodName, params)
        execJs(js, valueCallback)

    override fun execJs(sourceJs: String, valueCallback: ValueCallback<String>?) {
        if (ZJsBridge.ZJS_DEBUG) ZJsBridge.log("evaluateJavascript:javascript:$sourceJs")
        runOnMainThread(Runnable {
            evaluateJavascript("javascript:$sourceJs") { valueCallback?.onReceiveValue(it) }

    override fun runOnMainThread(runnable: Runnable) {
        if (Looper.getMainLooper() == Looper.myLooper()) {

AddJavascriptInterface during initialization

addJavascriptInterface(ZJavascriptInterface(this), "__zf")

Add a WebViewClient

private inner class InnerCustomWebViewClient : WebViewClient() {
    override fun onPageFinished(webView: WebView?, s: String?) {
        super.onPageFinished(webView, s)

    override fun doUpdateVisitedHistory(p0: WebView?, p1: String?, p2: Boolean) {
        super.doUpdateVisitedHistory(p0, p1, p2)

    override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
        val zWebResourceResponse = zWebHelper.hookNativeResourceWithWebViewRequest(request.url)
        if (zWebResourceResponse != null) {
            return WebResourceResponse(zWebResourceResponse.mimeType, "", zWebResourceResponse.data)
        return super.shouldInterceptRequest(view, request)

activity|fragment container registeredJsApiHandler

web_test.getCurZWebHelper().registeredJsApiHandler(this, CommonJsHandler::class.java)
web_test.getCurZWebHelper().registeredJsApiHandler(this, ImageJsHandler::class.java)

activity|fragment container implements IZWebViewContainer

override fun closeWindow() {

override fun updateTitle(title: String) {
    tv_test_tile.text = title

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    web_test.getCurZWebHelper().dispatchContainerResult(requestCode, resultCode, data)

override fun onDetachedFromWindow() {

override fun onBackPressed() {
    if (web_test.canGoBack()) {
    } else {

web test project

A packaged project has been integrated in the app module, which can be replaced with


Native-Bridge Agreement

nativeResourceUrl protocol