閱讀278 返回首頁    go 技術社區[雲棲]


PhoneGap Plugin與Wind.js結合,實現異步通信

      最近在做一個的ios的App。項目選擇了PhoneGap的移動跨平台框架。數據部分因為是某一小說網站的數據,通過ajax的跨域無法直接獲取,所以考慮Hybrid模式,把這一部分放在原生那裏去處理,然後通過Plugin來與頁麵JavaScript通信。到這裏問題出來了:在PhoneGap中,Plugin不是異步通信的。在執行通信模塊的時候,頁麵是不能動的,會出現假死的現象,頁麵的loading也無法動。

      查了很久的資源,發現:PhoneGap的javascript腳本與原生(iOS,android,wp等)的API的plugin交互,采用與瀏覽器webkit中的webview進行通信,而它的底層原理就是iframe的交互,它是以一種特定規範的通信協議來展開,而在傳統的web上iframe的使用本身就是最原始的異步加載原理的使用。所以,沒有辦法異步方式在phonegap的開發中廣泛使用。

      後來找到了老趙的Wind.js框架。通過簡單的代碼修改後。終於把問題解決了。下麵是相關的內容與解決的方法。

      首先介紹一下老趙的Wind.js:

      官方鏈接:https://windjs.org/

      開源鏈接:https://github.com/JeffreyZhao/wind

      Wind.js的異步模塊文檔:https://windjs.org/cn/docs/async/

      Wind.js簡單的介紹:

      Wind.js的前身為Jscex,即JavaScript Computation EXpressions的縮寫,它為JavaScript語言提供了一個monadic擴展,能夠顯著提高一些常見場景下的編程體驗(例如異步編程)。Wind.js完全使用JavaScript編寫,能夠在任意支持JavaScript的執行引擎裏使用,包括各瀏覽器及服務器端JavaScript環境(例如Node.js)。

        

       沒有引用Wind.js之前我的代碼:

       call.js:

var getNovelNames = function(url){
    console.log("與原生交互...");
	cordova.exec(
		function(result){
            		console.log("交互成功...");
			var html = '';
			var novelNames = result;
			for(var i=0; i<novelNames.length; i++){
				html +='<li><a href="#page2" data-transition="slide">'+novelNames[i]+'</a></li>';
			}
			
			$("#daylist").append(html);
           		$.mobile.hidePageLoadingMsg();
		},
		function(error){
            		alert('親,服務器繁忙,請重新刷新頁麵...');
        	},
		'CallPlugin',
		'getNovelNames',
		[url]
	);
};

index.js:

document.addEventListener('deviceready',function(){

                $.mobile.loadingMessageTextVisible = false;
                $("#day").bind("click",function(){
                            $.mobile.showPageLoadingMsg();
                            var url = '***'; //這裏為某網站的URL暫時屏蔽
                            getNovelNames(url);
          });
 },true);

        引入Wind.js

        首先在頁麵引入:

<script type="text/javascript" src="js/wind-all-0.7.3.js"></script>

    call.js變為:

var asyncNovelNames = function(url){
        $await(Wind.Async.sleep(1000)); //這裏停1s是為了讓loading看清楚。App上線後應移除
	cordova.exec(
		function(result){
			var html = '';
			var novelNames = result;
			for(var i=0; i<novelNames.length; i++){
				html +='<li><a href="#page2" data-transition="slide">'+novelNames[i]+'</a></li>';
			}
			
			$("#daylist").append(html);
                        $.mobile.hidePageLoadingMsg();
		},
		function(error){
                        alert('親,服務器繁忙,請重新刷新頁麵...');
                },
		'CallPlugin',
		'getNovelNames',
		[url]
	);
};

var getNovelNames =eval(Wind.compile("async", asyncNovelNames));

     index.js修改為:

document.addEventListener('deviceready',function(){
                $.mobile.loadingMessageTextVisible = false;
                $("#day").bind("click",function(){
                            $.mobile.showPageLoadingMsg();
                            var url = '***';//這裏為某網站的URL暫時屏蔽
                            var task = getNovelNames(url);
                            task.start();
                });
            },true);

       修改完成後,發現App還是會有假死的問題,檢查發現是原生問題的代碼執行的時候,如果時間過長還是會影響頁麵的顯示,這與website的區別很大。之前一直在做JavaEE方麵的項目,所以一下直沒考慮到這樣的問題。後來將數據請求問題的NSURLConnection改成是委托代理的模式。數據通信問題問題解決。



最後更新:2017-04-03 21:13:16

  上一篇:go WebLogic中修改端口號和省略端口號的做法
  下一篇:go WebLogic中修改端口號和省略端口號的做法