Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> [HyBrid]HyBrid混編初嘗:原生和第三方JsBridge的使用

[HyBrid]HyBrid混編初嘗:原生和第三方JsBridge的使用

編輯:關於Android編程

最近研究HyBrid的兩種方式:

一、直接原生WebView

1)初始化WebView:

	//啟動javascript
        webView = (WebView) findViewById(R.id.webView);
        //webView.setVerticalScrollbarOverlay(true);
        String uri = "file:///android_asset/js_test2.html";
        webView.loadUrl(uri);
        // 添加客戶端支持
        webView.setWebChromeClient(new WebChromeClient());
        // 設置WebView支持JavaScript
        webView.getSettings().setJavaScriptEnabled(true);
注釋比較清楚,不多解釋。

 

2)WebView與js通信

 

原生中代碼:

 

// 調用js中的函數:jsFun(msg)
        webView.loadUrl("javascript:jsFun('" + msg + "')");
直接通過Url加載javascript:+方法名

 

js中對應代碼:

 

//在java中調用此方法
function jsFun(msg){
alert("我是js方法,被java調用,傳遞過來的參數是:"+msg);
}

 

如此即可調用在native中調用js代碼:效果圖如下:

\

3)js與WebView通信

native中添加:

 

//  添加js交互接口
        webView.addJavascriptInterface(new MyJava(this), "javaObject");
addJavascriptInterface()源碼:

 

 

 * @param object the Java object to inject into this WebView's JavaScript
     *               context. Null values are ignored.
     * @param name the name used to expose the object in JavaScript
     */
    public void addJavascriptInterface(Object object, String name) {
        checkThread();
        mProvider.addJavascriptInterface(object, name);
    }
第一個參數是Object對象:將Object對象注入到WebView的JavaScript的上下文中。

 

第二個參數name:在JavaScript暴露對象使用的名稱。

通俗點講:也就是用第二個參數名字在js中使用,來引用第一個java對象。

我們這個例子中自定義了一個MyJava對象:

 

private class MyJava {
        private Context mContext;

        public MyJava(Context context) {
            this.mContext = context;
        }

        // 在js中調用window.javaObject.javaFun(name),便會觸發此方法。
        // api17版本以上加上注解
        @JavascriptInterface
        public void javaFun(String name) {
            Toast.makeText(mContext, "我是java方法,被js調用,js傳遞過來的參數是:" + name,
                    Toast.LENGTH_LONG).show();
        }
    }
構造方法直接忽略。這句注釋千萬不能忽略。

 

 

@JavascriptInterface
涉及到4.2以上版本能否使用。4.2之前有個安全漏洞,4.2之後修復的方式,是js調用native的方法,方法上必須通過該注釋注明才可以調用。

 

方法javaFun很簡單,不多說,直接看js中如何調用。

js中添加:

function sendInfoToJava(){
//js調用java方法,並傳遞參數
var value = document.getElementById("name_input").value;
window.javaObject.javaFun(value);
}
通過window.javaObject.javaFun(value)調用native的方法。之前已經解釋過javaObject引用MyJava對象。然後通過對象引用方法。
js引用native動畫效果如下:

 

\

二、JsBridge方法實現HyBrid

一、導入第三方類庫:

PS :JsBridge類庫地址。

二、Android Studio導入第三方類庫說簡單簡單,說難也難。

查看類庫結構:

\

導入步驟:

1)先復制上述第三方類庫到app平級處:如下

\

2)導入第三方類庫:如下圖:按順序:

\

\

\

此處上面的example就不要導入了。一個樣例,導入多余,還可能沖突。選擇finish。導入第三方完畢。

高興的太早了。主項目還調用不了這個導入的第三方包。

還需如下設置:

\

\

選擇之前的命名的第三方類庫,ok導入完畢。可以正常使用了。

三、使用JsBridge實現

PS:查閱了好多資料,之後總算是懂了。哎。好好學習,天天向上吧,少年。

通用部分:

1)使用JsBridge的WebView:BridgeWebView

xml:寫一個BridgeWebView

 




    
說明:

 

樣式很簡單:上面一個按鈕寫著:button 演示Java調用web。下面一個第三方自定義webView控件。

第一版資源文件demo.html:(Js看不懂,可以看完下面的描述再看)

 




<script>

    function connectWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge)
        } else {
            document.addEventListener(
                'WebViewJavascriptBridgeReady'
                , function() {
                    callback(WebViewJavascriptBridge)
                },
                false
            );
        }
    }
    connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(message, responseCallback) {
        console.log('JS got a message', message);
            responseCallback(data);
        });
        bridge.registerHandler("functionInJs", function(data, responseCallback) {
                document.getElementById("show").innerHTML = ("Native發來的消息是:" + data);
                var responseData = "Javascript Says Right back aka!";
                responseCallback(responseData);
            });
    })


</script>

2)直入主題:Native發送消息給H5

 

Acitivity中:通過上面的Native按鈕發消息給H5:

Activity初始化JsBridge:

 

	setContentView(R.layout.activity_main);
        webView = (BridgeWebView) findViewById(R.id.webView);
        webView.loadUrl("file:///android_asset/demo.html");
只需要找到加載H5資源即可。Native點擊事件如下:

 

 

@Override
    public void onClick(View v) {
        webView.callHandler("functionInJs", "傳遞消息給H5", new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
            }
        });
    }
H5如何能接收呢?如上注冊了一個functionInJs,那麼應該在H5中對應的寫法。

 

說到這,必須先說說

H5初始化JsBridge:

H5初始化JsBridge第一步:

 

connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(message, responseCallback) {
        console.log('JS got a message', message);
            responseCallback(data);
        });
    })

 

H5初始化JsBridge第二步:

 

function connectWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge)
        } else {
            document.addEventListener(
                'WebViewJavascriptBridgeReady'
                , function() {
                    callback(WebViewJavascriptBridge)
                },
                false
            );
        }
    }
知道在哪初始化了,那麼我就在[H5初始化JsBridge第一步]裡面注冊H5後如下:

 

 

connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(message, responseCallback) {
        console.log('JS got a message', message);
            responseCallback(data);
        });
        bridge.registerHandler("functionInJs", function(data, responseCallback) {
                document.getElementById("show").innerHTML = ("Native發來的消息是:" + data);
                var responseData = "Javascript Says Right back aka!";
                responseCallback(responseData);
            });
    })
加上這一段代碼就對應注冊了functionInJs。

 

看看動圖效果圖:

\

3)直入主題:H5發送消息給Native

第二版資源文件demo.html:

 




  <script>
    function go(){
        window.WebViewJavascriptBridge.callHandler(
            "Android",
            "Hello~",
            function(responseData){
                document.getElementById('a').innerHTML = 'Native給我的數據: ' + responseData;
            }
        );
    }

    function connectWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge)
        } else {
            document.addEventListener(
                'WebViewJavascriptBridgeReady'
                , function() {
                    callback(WebViewJavascriptBridge)
                },
                false
            );
        }
    }
    
    connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(message, responseCallback) {
        console.log('JS got a message', message);
            responseCallback(data);
        });
    })


</script>說明:比第一版本多了一個點擊事件。排除了第一版本的干擾Js代碼。(H5初始化JsBridge不變)

 

既然是H5調用Native:先看Js的點擊事件代碼:

 

function go(){
        window.WebViewJavascriptBridge.callHandler(
            "Android",
            "Hello~",
            function(responseData){
                document.getElementById('a').innerHTML = 'Native給我的數據: ' + responseData;
            }
        );
    }
三個參數分別是:第一個參數:注冊了一個Android。第二個參數:發送的消息內容是Hello~。第三個參數是一個回調。調用成功後,由Native返回responseData。

 

然後Native對應注冊Android:

 

 webView.registerHandler("Android", new BridgeHandler() {
            @Override
            public void handler(String s, CallBackFunction callBackFunction) {
                Toast.makeText(MainActivity.this, "H5給我的數據:" + s, Toast.LENGTH_SHORT).show();
                callBackFunction.onCallBack("fuck!");
            }
        });
這樣子,對應注冊完畢。

 

看個動圖效果圖:點擊1被點擊後,先彈出Native的Toast,然後回調了H5的內容文本。

\

正常來說,講到這兒,應該是講完了。但是這個第三方還自帶懶人功能:Native調用H5:不注冊參數。按照我們之前的例子來說就是不設置第一個參數functionInJs。反之,H5調用Native:不注冊參數也可以調用默認的Native功能。

4)Native默認設置:H5發送消息給Native。

寫一個類繼承默認處理類DefaultHandler

 

class MDefaultHandler extends DefaultHandler{
        @Override
        public void handler(String data, CallBackFunction function) {
            super.handler(data, function);
            Log.d(TAG,data);
            Toast.makeText(MainActivity.this,data,Toast.LENGTH_SHORT).show();
        }
    }

然後對WebView設置:

 

 

webView.setDefaultHandler(new MDefaultHandler());
Js調用的時候如何調用?

 

直接上demo.html:

 




  <script>
    function go(){
        window.WebViewJavascriptBridge.send(
        "被傳遞的Data"
        , function(responseData) {
            document.getElementById("a").innerHTML = "H5默認調用Native" + responseData
        }
    );
    }

    function connectWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge)
        } else {
            document.addEventListener(
                'WebViewJavascriptBridgeReady'
                , function() {
                    callback(WebViewJavascriptBridge)
                },
                false
            );
        }
    }

    connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(message, responseCallback) {
        console.log('JS got a message', message);
            responseCallback(data);
        });
    })


</script>可見只是這兒有所修改:

 

 

window.WebViewJavascriptBridge.send(
        "被傳遞的Data"
        , function(responseData) {
            document.getElementById("a").innerHTML = "H5默認調用Native" + responseData
        }
    );
改變:只有兩個參數了。方法名變成了send。
看看動畫效果圖:

 

\

5)Js默認設置:Native發送消息給H5。

看看Js初始化第一步:

 

connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(message, responseCallback) {
        console.log('JS got a message', message);
            responseCallback(data);
        });
    })

此處的message其實就是默認的發來的消息。

 

Native發送默認消息方式非常簡單:點擊事件裡面調用一下即可:

 

@Override
    public void onClick(View v) {
        webView.send("hello來自Native的默認消息");
    }
為了方便驗證:將Js初始化第一步改成如下:

 

 

connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(message, responseCallback) {
        document.getElementById("a").innerHTML = "來自Native的:" + message;
            responseCallback(data);
        });
    })
也就是在id等於a的文本處展示。

 

動圖效果圖如下:

\

Over~打算再寫一章關於JsBridge的原理,看看我能不能讀懂大神的源碼吧。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved