Hybrid App 開發模式


  開發移動App主要有三種模式:Native、 Hybrid 和 Web App。

  需要注意的一點是在選擇開發模式的時候,要根據你的項目類型(圖片類?視頻類?新聞類?等),產品業務和人員技術儲備等做權衡。

  Hybrid開發模式就是既有Native開發也有Web app的開發。那我們怎么去確定App中某個功能模塊使用Native還是Web開發?它們之間如果需要接口通信又該如何去實現呢?又該如何更好的去維護Hybrid App產品呢?

1、Native or Web開發模塊

  當我們選擇用Hybrid模式開發App時,應先熟悉項目整個框架和App各個模塊。然后將通用的,對性能要求不是那么高的App界面可抽出來作為web界面開發,Native直接調用。一般Hybrid App開發,App界面之間的跳轉關系由Native實現並完成,web界面主要作為內容填充到Android和iOS的瀏覽器控件中。拉手網之前Android客戶端就是采用這種模式,Native搭一個App框架殼,里面展示內容和網絡請求全部由web實現。由於客戶端瀏覽器控件版本不同,web界面加載,渲染和緩存機制等原因,這種模式開發的App整體在圖文比較多的情況下體驗就不太好,甚至可能會出現意想不到的奇葩問題。 建議圖文列表,涉及到視頻等多並發和界面元素比較負責或具有很強的動畫特效的情況優先考慮Native開發。 這方面在Android尤其有必要,Android 4.4之前的瀏覽器控件WebView基於缺省的WebKit內核,它不同於Chromium所使用的Webkit內核;而在4.4之后(包括4.4)的WebView的實現被替換成Chromium WebKit內核。當我們想讓App盡可能的在低版本也能運行良好時,就需要不斷做兼容性開發和測試了,除非自己在App里面打包編譯最新WebView源碼,類似開發一個瀏覽器。

2、Native & web 通信

  • Native調用js方法

Android和iOS都提供了API直接調用:

webview.loadUrl("javascript:functionName(\"" + argument + "\")");

別忘了設置 webview.getSettings().setJavaScriptEnabled(true);  

[webView stringByEvaluatingJavaScriptFromString:@"alert('hello world!')"];
  • js調用Native方法。

Android實現js調用native方法一般是先編寫供js調用的類,然后通過添加javascripteInterface的方法,如

webView.addJavascriptInterface(pandoInterface, "pando");

  將java對象pandoInterface生成js對象pando,然后直接window.pando就可以調用pandoInterface對象里面的方法。需要注意的是供js調用的pandoInterface對象里面的java方法需手動加上@JavascriptInterface注解,這個是Google為解決安全問題引入的。

  iOS實現js調用Native方法相對繁瑣一點。主要是iOS原生並沒有提供js直接調用native的方式,只能通過UIWebView相關的UIWebViewDelegate協議的方法來做攔截,並在這個方法中,根據url的協議或特征字符串來做調用方法或觸發事件等工作。當js需要調用Native方法時,js創建一個隱藏的iframe設置或改變其src就會觸發Native攔截url事件。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSURL *url = [request URL];
    if ([[url scheme] isEqualToString:@"someFunction") {
        //調用原生方法
        return NO;
    } else {
        return YES;
    }
}

 

  不知道大家發現沒有,以上兩種方法都只是實現了js調用Native方法,但是都沒有實現js函數回調,將Native方法返回結果傳遞給js。

  微信開放了很多jsApi接口,供大家直接調用微信Native的功能。通過jsApi接口和文檔我們會發現里面實現了Native方法執行結果回調給js。這種Hybrid App開發模式很好的利用了Native高性能,多並發的優勢,將網絡請求,掃碼等復雜的邏輯或者web不可能實現的功能由Native完成,而web只是做了界面顯示效果。將微信Android安裝包解壓之后,在assets/jsapi目錄下有個80多kb的wxjs.js文件,里面實現了微信jsApi邏輯jsbridge。下面主要簡單介紹一下這種jsbridge實現原理。

  jsbridge核心難點在於如何在Native方法執行完之后將返回接口給js,並且讓js能理解傳過來的參數所表達的意思。針對這,我們可以在js調用Native方法之間,將js一次調用Native的唯一標示符identifier和期望Native調用完后執行的回調函數存儲在Map里面,將identifier和其他參數傳遞給Native,native執行完成后,將identifier和執行結果作為參數調用js函數,在js函數里面解析參數,得到identifier,然后在Map里查詢對應的回調函數,將native執行結果作為參數傳遞進去調用。有點繞,但是巧妙的利用消息傳遞機制,實現js調用Native進行回調函數調用,同理,Native調用js函數將返回結果給Native調用也是可以的。

  Android在實現jsbridge時,早期方法也是需要iOS那樣,先給web界面創建iframe,然后通過js改變iframe src,Native方法通過shouldOverrideUrlLoading(WebView view, String url)攔截url處理。但是在Android 4.2.2系統上,這個方法在iframe src改變是,是不會觸發的。目前建議大家通過攔截js alert彈框做處理。

@Override
public boolean onJsAlert(WebView view, String url, String message,
                JsResult result) {
    LogUtils.i("url:" + url+"\n message:" + message);
    try {
        String msg = URLDecoder.decode(message, "utf-8");
        if (msg.startsWith(BridgeUtil.PANDO_RETURN_DATA)) { // 如果是返回數據
            handlerReturnData(message);
            result.cancel();
            return true;
        }
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return super.onJsAlert(view, url, message, result);

}

 

  注意,onJsAlert方法攔截做處理后一定要result.cancel();不然web界面就會出現點擊沒反應的情況。

3、Hybrid App維護

Hybrid App涉及到html、css和js等web資源文件,當web和Native之間有相互調用時,兩者之間任何一方接口變動都會導致App出現bug。

  • 考慮類似微信方案,將jsbridge文件或者部分常用web資源隨App打包發布,降低維護成本,也不用擔心在網絡不好的情況下加載不了web界面,在接口升級之前發布出去的App肯定也是穩定可用的,當然這個也要考慮安全性問題,畢竟你的web界面源碼通過反編譯代碼可以得到。
  • 所有web資源統一從服務器獲取。由於web資源在服務器,所以可以隨時動態更改web界面,發現bug也不用發布App,直接在線接口升級。但是要維護web資源,使得每個發布出去的每個版本的App在加載web資源時都可用。

 

討論:

  Q:

最近想自己寫個android的hybrid app,看了下大多推薦的是PhoneGap,不知道他的運行效率怎么樣,如果以原生為重的話,適不適合用PhoneGap?

  A:

我來說說吧,其實就是mui開發最快,這是我自己實踐的結果,ionic我沒用,可是cordova我用過,因為國內沒多少人分享經驗,所以坑很多。

你做一個帶掃碼,搖一搖,地理位置追蹤,消息推送的app,這些基礎功能mui基本不用研究拿來就能用。cordova光是研究插件集成和使用就得花3天時間,中間還會有很多坑。(這個已經有半成品)

但是,cordova對於你做一個需求比較奇特的app來說很好,因為他的插件庫全。mui對這個支持比較弱。(這個試了一周后放棄)

話又說回來,如果那么奇特需求的app在技術選型上為什么不選原生?如果非得用hybird自己用webview做就是了。學cordova的時間夠把如何原生調用js和js調用原生弄明白10次了。現在我就是這么做的。

A:  

  如果對原生的部分功能要求較高的話,不推薦使用PhoneGap,雖說現在已經很成熟,但是如果涉及到原生功能還是很差的,我之前體驗過。。

 

---------------------------分------------割------------------------------------- 

 

以上內容摘自 

https://www.tuicool.com/articles/riE3Yn

感謝大神們的實踐總結~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM