構建一個完整的Cordova應用

本文承接上篇《建立Cordova插件》,經過實現一個簡單的應用做爲這個Cordova初級系列的結束。javascript

前邊對Cordova編程已經講了很多了,尚未拿真實應用爲例完整的演練一遍構建過程。這裏將用一個完整的應用爲例從頭至尾一步步的演示如何建立和測試應用。css

關於示例應用

把全部的API集中在一個例子中展現是一個好辦法。下面咱們以實現一個指南針錶盤爲例。html

應用在屏幕上顯示一個表示指南針轉盤的圖像。當用戶沿着水平座標軸轉動設備時,指南針圖像也轉動。應用效果以下圖:java

圖片描述

這裏會用到jQuery Mobile提高用戶UI,還會利用Cordova merges文件夾爲Android和iOS提供不一樣的圖像(方便起見下面只在Android平臺開發)。jquery

建立應用

在開發文件夾中用CLI建立Cordova項:android

cordova create compass
cd compass
cordova platform add android

這時咱們就有了一個新的Cordova項目,它支持Android平臺。項目中可能會用到一個或多個核心插件。能夠訪問Cordova CLI使用指南網站,找到包含向項目添加每一個Cordova插件的完整命令說明。 ios

咱們要在程序中調試應用,須要向控制檯寫信息,參照指南中添加console插件的命令,以下:git

cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-console.git

應用使用了指南針,還須要使用以下命令添加compass插件。apache

cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-orientation.git

注意若是不在Cordova工做時打開-d開關,它不會向你輸出執行過程信息。編程

接下來複制之前示例中的index.html到項目的www目錄。用以下代碼編輯這個頁面:

<body onload="onBodyLoad()">
    <h1>Example 13-2</h1>
    <img src="compass.png" id="compass" />
    <br />
    <p id="headingInfo"></p>
</body>

爲了把應用作的漂亮些,可使用jQuery Mobile把應用建立的更像移動應用。首先下載jQuery和jQuery Mobile,複製到www目錄中,並向index.html頁的head部分添加對它們的引用。

<link rel="stylesheet" href="jquery.mobile-1.3.2.min.css />
<script type="text/javascript" charset="utf-8" src="jquery-2.0.3.min.js"></script>
<script type="text/javascript" charset="utf-8" src="jquery.mobile-1.3.2.min.js"></script>

應用旋轉圖像的能力由一個叫jQuery Rotate的免費插件實現;你能夠在http://code.google.com/p/jqueryrotate 找到關於這個插件的信息。要添加插件,把這個插件的js文件放在www文件夾中,而後在index.html中添加以下一行script標籤:

<script type="text/javascript" charset="utf-8" src="jQueryRotateCompressed.js"></script>

當須要的jQuery文件都就位後,把index.html的body部分更新成下面這樣:

<body onload="onBodyLoad()">
    <div data-role="page">
        <div data-role="header">
            <h1>指南針</h1>
        </div>
    </div>
    <div data-role="content">
        <div style="text-algin:center;">
            <img src="img/compass.png" id="compass" alt="">
            <br/>
            <p id="headingInfo">
                <b>Heading:</b> 0 Degreess
            </p>
        </div>
    </div>
    <div data-role="footer" data-position="fixed">
        <h3>Created By Af</h3>
    </div>
</body>

是jQuery Mobile使用元素中的data-role屬性來把這些特殊的元素定義成適當的外觀。所以在前面的例子中,在頁面上建立了一個header div並把它的data-role賦爲header,一樣把footer div的data-role屬性設置爲footer。data-position="fixed"把頁腳固定在頁面底部。

接下來我把頁面的內容放在一個屬性data-role是content的div中。爲了加載指南針圖像,並在頁面居中顯示朝向信息,添加一個新的div並設置成"style="text-algin:center"的樣式。

注意 爲了避免顯得雜亂,沒有把style特性放在data-role爲content的div中。也方便說明學習重點。

如今已經升級了用戶界面,是時候開始關注應用的js代碼了。在應用的index.html的script標籤中定義了一些應用用到的函數。

第一個要用到的是響應window.onerror事件的函數。由於咱們知道代碼不會正確執行,而且多數時候Cordova應用發生錯誤時都是保持靜默的,這樣爲這個事件賦值並關聯處理函數以便於發現發生在運行應用上的錯誤。下面展現的這個函數,基本上是接受了一個錯誤,應用文件名URL碰到了這個錯誤,而且行號引發了這個錯誤;而後它產生了適當的錯誤信息並把它寫到日誌,顯示到對話框上。

// 遇到錯誤時觸發
window.oneeror = function(msg, url, line) {
    var resStr;
    var index = url.lastIndexOf('/');
    if (index > -1) {
        url = url.substring(index + 1);
    }
    resStr = 'Error in ' + url + ' on line ' + ': ' + msg;
    console.log(appName + resStr);
    alert(resStr);
    return false;
}

接下來是通篇都用到的onDeviceReady函數。它做爲Cordova的deviceready事件的監聽器建立,而且在Cordova容器完成初始化後觸發。在這個函數中瞭解到Cordova容器準備好了,這樣可作想作的一切了。如下是這個函數:

function OnDeviceReady() {
    console.log('onDeiveReady fired.');
    hi = document.getElementById('headingInfo');
    // 設置監視
    // 每秒(1000毫秒)讀指南針
    var watchOptions = {
        frequency : 1000
    };
    console.log(appName + 'Creating watch: ' + JSON.stringify(watchOptions));
    watchID = navigator.compass.watchHeading(onSuccess, onError, watchOptions);
}

函數首先定義了一個hi變量,它指向ID爲headingInfo的頁面元素。變量稍後用來用展現設備朝向的元素替換內容。

接下來函數定義了一個watchOptions變量,它用來設置一個朝向監視,這個監視可讓應用按期更新朝向。watchOptions對象便可以給它的frequency屬性或filter屬性賦值。

當使用朝向監視時,它每1000毫秒會讓Compass API報告設備朝向。filter屬性用來在報告朝向前定義朝向變化的數量(用度)。下面的例子filter屬性告訴Compass API每秒發佈大於1度的朝向:

var watchOptions = {
    filter: 1
};

這裏能夠指定這兩個屬性,但要是指定了filter,frequency屬性會被Compass API忽略。

注:此處是坑。Android已經不支持filter。

var watchOptions = {
    frequencey: 1000,
    filter: 1
};

定義watchOptions後,函數調用watchHeadin來建立朝向監視:

watchID = navigator.compass.watchHeading(onSuccess, onError, watchOptions);

就像已經瞭解的全部其餘Cordodva API同樣,onSucces函數在Compass API發送一個朝向值時執行,onError函數在Compass API遇到錯誤時執行。

當執行onSuccess時,Compass API把heading對象傳遞過來,它包括表示設備朝向的屬性,以下:

{
    "magneticHeading":0,
    "trueHeading":0,
    "headingAccuracy":0,
    "timestamp":137873854661
}

onSuccess函數使用heading對象的magneticHeading屬性來肯定當前朝向,而後使用這個值按照度數旋轉指南針圖像,就像下面函數展現的:

function onSuccess(heading) {
    console.log(app.Name + 'Received Heading');
    console.log(appName + JSON.stringify(heading));
    var hv = Math.round(heading.magneticHeading);
    console.log(appName + 'Rotating to ' + hv + ' degrees');
    $("#compass").rotating(-hv);
    hi.innerHTML = '<b>Heading:</b> ' + hv + ' Degrees';
}

注意指南針圖像以設備當前朝向相反的方向旋轉。這是由於設備被轉動,指南針圖像必須以相反的方向轉動,這樣指南針的北方老是指向磁極的北方。

最後應用的onError函數在監視發生錯誤時執行。它用傳遞給函數的error對象來識別錯誤的緣由併爲用戶顯示適當的錯誤信息。注意onError函數還取消了監視,由於在應用不能測量朝向時繼續監視朝向也沒有太大意義了。

function onError(err) {
    console.error(appName + 'Heading Error');
    console.error(appName + 'Error: ' + JSON.stringify(err));
    // 發生問題移除監視
    navigator.compass.clearWatch(watchID);
    // 在頁面上清除朝向值
    hi.innerHTML = '<b>Heading: </b>None';
    // 告之用戶
    if (err.code == CompassError.COMPASS_NOT_SUPPORTED) {
        aleert('不支持指南針');
    } else if (compassError.code == CompassError.COMPASS_INTERNAL_ERR) {
        alert('指南針內部錯誤');
    } else {
        alert('未知的朝向錯誤');
    }
}

注意比以往其餘應用更屢次的寫控制檯。這麼作是爲了更真實的展現建立Cordova應用。屢次使用控制檯寫出全部遇見的應用對象,這讓咱們更好的瞭解從應用中得到了什麼,這樣能在發生錯誤時更容易的調試問題。

在應用中定義一個appName對象:

var appName = "Compass - ";

當應用寫控制檯時,把appName的值追加到每一個記錄中:

console.error(appName + 'some message');

當在Android上調試時,能夠用監視器應用來查看實時的日誌記錄。就像14.4展現的,你能夠用appName過濾傳入的值以便只查看這個應用的控制檯信息。

測試應用且它是合意的,移除或標註多處應用寫控制檯的地方。

完整的index.html請參考源碼。

使用Merges

如今尚未提過Cordova CLI的merge功能。前面"Cordova開發機制"解釋過它怎樣工做,這裏展現它的使用。

假設項目在compass文件夾中,把Android平臺的指南針圖像compass.png放在compass/merges/android/img/中,把iOS版本的放在merges/ios/img/中。在構建過程當中,Cordova CLI把merges中的android文件夾的圖像複製到compass/platforms/android/assets/www/img/中。ios也是一樣的作法。

結果是能夠維護一套代碼並在須要的正確資源中按照平臺切換。這對不一樣平臺來講更加易於管理資源。

最後注意在模擬器上通常沒有指南針,須要須要在真機上測試這個應用。

轉眼就到2015年末了,最近幾個月有些事就沒有持續寫。最近想起來好像提到過這個系列應該有個收尾,就不要讓它跨年了。另外最近看了看一些其餘技術,像ReactJS、ASP.NET Web API、Kotlin等,還正在讀一些軟件構建技術方面的經典(慚愧,應該是早就讀過的),但願本身能持續把學習和實踐中的一些粗淺認識拿出來曬(如今通常是分段分享在微博@AfternoonLeaf),期待與您共同進步。

相關文章
相關標籤/搜索