Cordova安裝使用

                                       本文來自http://blog.csdn.net/liuxian13183/ ,引用必須註明出處!

      H5交互的框架很多,如ReactNative、Weex等,也有直接用JsBridge和WebAppInterface的方式,至於用哪種實現方式,主要看業務複雜度以及重要性。

拍板Cordova原因如下:

1、支持Android、iOS、Sybian等主流手機操作系統

2、使用時間長,被衆多知名公司使用,踩過的坑足夠多,資料查找方便

3、總監自己比較熟悉,有助於支持項目快速推進。

總之技術選型完畢,大家就開始準備落實方案。

     先去查一下官方介紹:http://cordova.axuer.com/docs/zh-cn/latest/guide/platforms/android/index.html

cordova安裝
要求:NodeJs
要求:Jdk64位

npm出現npm err windows_nt 6.1.7601錯誤

npm config set https-proxy null

npm config set strict-ssl false

npm install -g cnpm –registry=https://registry.npm.taobao.org

便利性在於:支持同步和異步調用(需要自己寫相關插件)

下載完之後,咱們把cordova加入項目

1、這部分代碼放入assets目錄:


2、這部分代碼加入依賴

3、把config.xml文件放在這裏

<?xml version='1.0' encoding='utf-8'?>
<widget xmlns:cdv="http://cordova.apache.org/ns/1.0" id="com.company.packagename" version="1.0.0"
        xmlns="http://www.w3.org/ns/widgets">

    <feature name="Whitelist">
        <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin"/>
        <param name="onload" value="true"/>
    </feature>

    <feature name="SyncService">
        <param name="android-package" value="com.cordova.plugin.SyncServicePlugin"/>
        <param name="onload" value="true"/>
    </feature>

    <feature name="AsyncService">
        <param name="android-package" value="com.cordova.plugin.AsyncServicePlugin"/>
        <param name="onload" value="true"/>
    </feature>

    <name>HelloWorld</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="[email protected]" href="http://cordova.io">
        Apache Cordova Team
    </author>

    <content src="index.html"/>
    <access origin="*"/>
    <allow-intent href="http://*/*"/>
    <allow-intent href="https://*/*"/>
    <allow-intent href="tel:*"/>
    <allow-intent href="sms:*"/>
    <allow-intent href="mailto:*"/>
    <allow-intent href="geo:*"/>
    <allow-intent href="market:*"/>
    <preference name="loglevel" value="DEBUG"/>
    <preference name="errorUrl" value="file:///android_asset/client-local/500.html"/>
</widget>

重點有4,分別是packageName、syncServicePlugin(同步插件)、asyncServicePlugin(異步插件)和errorUrl

4、設置CordovaPlugin的shouldAllowNavigation的返回值爲true,否則H5調不到本地插件

5、寫插件實現功能

    @Override
    public boolean execute(String action, final String rawArgs, CallbackContext callbackContext)
            throws JSONException {
        if (action.equals("js_viewImageAction")) {
            try {
                JSONArray array = new JSONArray(rawArgs);
                JSONObject args = array.optJSONObject(0);
                JSONArray imgArray = args.optJSONArray("img");
                int index = args.optInt("index");
                String[] target = new String[imgArray.length()];
                for (int i = 0; i < imgArray.length(); i++) {
                    target[i] = imgArray.getString(i);
                }
                Intent intent = new Intent(cordova.getActivity(), ImageViewActivity.class);
                intent.putExtra(IntentConstants.IMAGE_URLS, target);
                intent.putExtra(IntentConstants.IMAGE_INDEX, index);
                cordova.getActivity().startActivity(intent);
                callbackContext.success();
                return true;
            } catch (Exception e) {
                Logger.t(TAG).e("js_viewImageAction failed" + e);
            }
        } 
      return super.execute(action, rawArgs, callbackContext);
    }

js_viewImageAction即插件名字。

通過JsonArray(據說iOS無法使用json傳數據),獲得json傳遞數據(注意要調callbackContext.success方法,使h5能確認native已經接收到;當然也可以用success方法回傳json結果數據),同時return true 代碼插件已被處理,不必再分發。

注意點:插件每次進入都會被初始化。

後面打算再插入一點WebView的知識點:

WebView狀態管理

//激活WebView爲活躍狀態,能正常執行網頁的響應
webView.onResume() ;

//當頁面被失去焦點被切換到後臺不可見狀態,需要執行onPause
//通過onPause動作通知內核暫停所有的動作,比如DOM的解析、plugin的執行、JavaScript執行。
webView.onPause();

//當應用程序(存在webview)被切換到後臺時,這個方法不僅僅針對當前的webview而是全局的全應用程序的webview
//它會暫停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
webView.pauseTimers()
//恢復pauseTimers狀態
webView.resumeTimers();

//銷燬Webview
//在關閉了Activity時,如果Webview的音樂或視頻,還在播放。就必須銷燬Webview
//但是注意:webview調用destory時,webview仍綁定在Activity上
//這是由於自定義webview構建時傳入了該Activity的context對象
//因此需要先從父容器中移除webview,然後再銷燬webview:
rootLayout.removeView(webView); 
webView.destroy();

Js交互,4.4以上

// 只需要將第一種方法的loadUrl()換成下面該方法即可
    mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            //此處爲 js 返回的結果
        }
    });
}

加載速度:使用本地資源(來源於隨時服務端推送)

public class MainActivity extends AppCompatActivity {
    
    WebView mWebview;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mWebview = (WebView) findViewById(R.id.webview);
        // 創建WebView對象

        mWebview.getSettings().setJavaScriptEnabled(true);
        // 支持與JS交互

        mWebview.loadUrl("http://ip.cn/");
        // 加載需要顯示的網頁

        mWebview.setWebViewClient(new WebViewClient() {

             // 複寫shouldInterceptRequest
             //API21以下用shouldInterceptRequest(WebView view, String url)
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

                // 步驟1:判斷攔截資源的條件,即判斷url裏的圖片資源的文件名
                // 此處網頁裏圖片的url爲:http://s.ip-cdn.com/img/logo.gif
                // 圖片的資源文件名爲:logo.gif

                if (url.contains("logo.gif")) {

                    InputStream is = null;
                    // 步驟2:創建一個輸入流


                    try {
                        is =getApplicationContext().getAssets().open("images/error.png");
                        // 步驟3:打開需要替換的資源(存放在assets文件夾裏)
                        // 在app/src/main下創建一個assets文件夾
                        // assets文件夾裏再創建一個images文件夾,放一個error.png的圖片

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    // 步驟4:替換資源

                    WebResourceResponse response = new WebResourceResponse("image/png",
                            "utf-8", is);
                    // 參數1:http請求裏該圖片的Content-Type,此處圖片爲image/png
                    // 參數2:編碼類型
                    // 參數3:替換資源的輸入流

                    System.out.println("舊API");
                    return response;
                }

                return super.shouldInterceptRequest(view, url);
            }


            // API21以上用shouldInterceptRequest(WebView view, WebResourceRequest request)
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

                // 步驟1:判斷攔截資源的條件,即判斷url裏的圖片資源的文件名
                // 此處圖片的url爲:http://s.ip-cdn.com/img/logo.gif
                // 圖片的資源文件名爲:logo.gif
                if (request.getUrl().toString().contains("logo.gif")) {

                    InputStream is = null;
                    // 步驟2:創建一個輸入流

                    try {
                        is = getApplicationContext().getAssets().open("images/error.png");
                        // 步驟3:打開需要替換的資源(存放在assets文件夾裏)
                        // 在app/src/main下創建一個assets文件夾
                        // assets文件夾裏再創建一個images文件夾,放一個error.png的圖片

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    //步驟4:替換資源
                   
                    WebResourceResponse response = new WebResourceResponse("image/png",
                            "utf-8", is);
                    // 參數1:http請求裏該圖片的Content-Type,此處圖片爲image/png
                    // 參數2:編碼類型
                    // 參數3:存放着替換資源的輸入流(上面創建的那個)
                    
                    return response;
                }
                return super.shouldInterceptRequest(view, request);
            }

    });

}
}

安全方面:

禁用file協議及相關js調用

// 需要使用 file 協議
setAllowFileAccess(true); 
setAllowFileAccessFromFileURLs(false);//true,則可從file裏的js,讀取本地私密源
setAllowUniversalAccessFromFileURLs(false);//true,則可從file裏的js,讀取所有源

// 禁止 file 協議加載 JavaScript
if (url.startsWith("file://") {
    setJavaScriptEnabled(false);
} else {
    setJavaScriptEnabled(true);
}

3.0以下刪除WebView內置導出的“searchBoxJavaBridge_”、“accessibility ”、“accessibilityTraversal”

更多WebView知識點:https://www.jianshu.com/p/3c94ae673e2a

有問題歡迎評論!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章