android hybird 完成:自定義schema

android hybird 與h5 app區分

hybird 與h5 app是不一樣的,之前對這兩者明白有所誤會,在現實開闢中也並未真正採納hybird,而是運用h5+app外殼完成挪動端運用。雖然開闢出來的運用完成了無需晉級app完成主功用更新,然則交互體驗上較原生相差甚多。
Hybrid App(夾雜情勢挪動運用)是指介於web-app、native-app這兩者之間的app,兼具“Native App優越用戶交互體驗的上風”和“Web App跨平台開闢的上風”(摘自百度百科)
平常hybird app會將須要動態更新頁面及功用內置到app中,也就是將web頁面預置到當地,android端經由過程加載當地html頁面完成疾速加載,因為不須要經由收集,速率上會有極大的提拔。而須要晉級是,則需在服務器上豎立對應的資本包,並將服務器資本包與當地html版本做對照,若不一致則從服務器加載資本壓縮包,並下載到當地,從而完成不須要重新安裝app疾速晉級迭代的目標。此功用適用於須要頻仍更新,又對機能請求較高的場景,比方消息頭條頁等。若用h5完成,則體驗上會相差不少。

android 與js夾雜挪用體式格局

1.一般android與js夾雜挪用的體式格局是android端定義webView,並設置以下代碼

    WebSettings settings = mWebView.getSettings();

    settings.setJavaScriptEnabled(true);
    //設置本運用加載網頁
   mWebView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url)     {
                view.loadUrl(url)
                return true;
            }
        });
       mWebView.loadUrl("***.html");

此處傳入url並開啟接見收集權限即可完成翻開頁面.AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

下面正式最先JS挪用android體式格局
須要豎立一個橋,以下


import android.content.Context;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

public class JsInterface {
    private Context mContext;
    public JsInterface(Context context){
        mContext = context;
    }
    //必需加註解,為了平安性斟酌,4.2后強迫
    @JavascriptInterface
    public void showToast(String params){
        Toast.makeText(mContext,"Hello"+params,Toast.LENGTH_LONG).show();
    }

}


//MainActivity中
        JsInterface jsInterface = new JsInterface(MainActivity.this);
        myWebView.addJavascriptInterface(jsInterface,"bridge");
 //js中,運用以下代碼
    document.getElementById('#btn').addEventListener("click",function(){
        if(window.bridge){
            window.bridge.showToast('from js methods');
        }
    })

此時js能夠勝利 挪用到android中原生要領,然則回調會很貧苦,4.4中有evaluatejavascript能夠完成,然則未兼容到4.4以下。至此,因為本文中的重點,hybird的完成計劃及js與android交互計劃。

hybird中的完成體式格局

道理與android中原生schema協定相似,經由過程阻攔URl情勢完成。能夠經由過程自定義協定稱號,然後webView中阻攔這個schema,並剖析个中參數與回調函數,js挪用android要領,並完成回調。
起首定義協定,即須要阻攔的scheme ,我在這裏定義 myschema://utils,這個協定名能夠是恣意的,只需阻攔一致即可。
封裝的js要領以下

function invoke(action, data, callback) {
        // 拼裝 schema 協定,action對應須要完成的要領名
        var schema = 'myshema://utils/' + action

        // 拼接參數 data對應參數 
        schema += '?a=a'
        var key
        for (key in data) {
            if (data.hasOwnProperty(key)) {
                schema += '&' + key +"="+ data[key];
            }
        }

        // 處置懲罰 callback
        var callbackName = ''
        if (typeof callback === 'string') {
            callbackName = callback
        } else {
            callbackName = action + Date.now()
            window[callbackName] = callback
        }
        schema += '&callback='+callbackName;
        //終究拼接出來應該是zhezhong這類情勢 myshema://utils/actioin?a=a&key=value&callback=callbackName
        // 觸發
        var iframe = document.createElement('iframe')
        iframe.style.display = 'none'
        iframe.src = schema  // 主要!此處會發送銜接,會被webviwe捕獲到
        var body = document.body
        body.appendChild(iframe)
        setTimeout(function () {
            body.removeChild(iframe)
            iframe = null
        })
    }
    

index中

 document.getElementById('btn1').addEventListener('click', function () {
            // invokeScan()
            invoke('showToast',{name:'js'},function(res){
                console.log("回調勝利",res)'
            })
            //location.href="http://www.baidu.com";
        })

android中,將js文件與index文件安排與assets文件夾下,webView加載此index,並設置阻攔,代碼以下

 myWebView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //主要,此處完成阻攔,可剖析參數,依據action稱號挪用差別要領,此處未演示
                if(url.contains("myshema://utils/")){
                    Toast.makeText(MainActivity.this,"挪用勝利",Toast.LENGTH_LONG).show();
                    String callback = "";
                    Map<String,String> params = UriUtil.URLRequest(url);
                    if(params.containsKey("callback")){
                        view.loadUrl("javascript:"+params.get("callback")+"()");
                    }

                }else{
                    view.loadUrl(url);
                }
                return true;
            }
        });
        myWebView.loadUrl("file:///android_asset/index.html");

至此,完成了經由過程自定義schema完成js阻攔挪用android原生要領的計劃,此計劃優點是能夠隱蔽挪用細節,將挪用細節封裝到內部,更平安,而且兼容性更好.
如有題目,迎接發問並與我聯絡,轉載請說明作者!

    原文作者:驀然回首
    原文地址: https://segmentfault.com/a/1190000015304870
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞