构建一个完整的Cordova应用

标签: cordova | 发表时间:2015-12-23 06:26 | 作者:AfternoonLeaf
出处:http://segmentfault.com/blogs

本文承接上篇《创建Cordova插件》,通过实现一个简单的应用作为这个Cordova初级系列的结束。

前边对Cordova编程已经讲了不少了,还没有拿真实应用为例完整的演练一遍构建过程。这里将用一个完整的应用为例从头到尾一步步的演示如何创建和测试应用。

关于示例应用

把所有的API集中在一个例子中展示是一个好办法。下面我们以实现一个指南针表盘为例。

应用在屏幕上显示一个表示指南针转盘的图像。当用户沿着水平坐标轴转动设备时,指南针图像也转动。应用效果如下图:

图片描述

这里会用到jQuery Mobile提升用户UI,还会利用Cordova merges文件夹为Android和iOS提供不同的图像(方便起见下面只在Android平台开发)。

创建应用

在开发文件夹中用CLI创建Cordova项:

  cordova create compass
cd compass
cordova platform add android

这时我们就有了一个新的Cordova项目,它支持Android平台。项目中可能会用到一个或多个核心插件。可以访问Cordova CLI使用指南网站,找到包含向项目添加每个Cordova插件的完整命令说明。

我们要在程序中调试应用,需要向控制台写信息,参照指南中添加 console插件的命令,如下:

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

应用使用了指南针,还需要使用如下命令添加compass插件。

  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等,还正在读一些软件构建技术方面的经典(惭愧,应该是早就读过的),希望自己能把学习和实践中的一些粗浅认识拿出来晒,期待与您共同进步。

相关 [建一 完整 cordova] 推荐:

构建一个完整的Cordova应用

- - SegmentFault 最新的文章
本文承接上篇《创建Cordova插件》,通过实现一个简单的应用作为这个Cordova初级系列的结束. 前边对Cordova编程已经讲了不少了,还没有拿真实应用为例完整的演练一遍构建过程. 这里将用一个完整的应用为例从头到尾一步步的演示如何创建和测试应用. 把所有的API集中在一个例子中展示是一个好办法.

cordova与ios native code交互的原理

- - CSDN博客推荐文章
很早以前写了一篇博客,总结cordova插件怎么调用到原生代码: cordova调用过程,不过写得太水,基本没有提到原理. 最近加深了一点理解,重新补充说明一下. 下面是我们产品中的代码片段:. cordova插件最终表现出来的都是js接口,并且调用者完全不需要知道自己在调用一个cordova插件.

基于Apache Cordova开发移动平台上的Chrome Apps

- - Chrome迷
不好意思,迟到的新闻,同时给大家拜个晚年,祝大家马年吉祥马上有钱. 据去年9月份的消息,Chrome Apps将可以像原生应用一样在各终端设备上离线运行,目前已经做到兼容了所有的桌面平台. 而现在通过一个基于 Apache Cordova的开发者预览版工具包,Chrome Apps已经实现可以直接在Android和iOS设备上运行了.

最佳(也许)实践:开始用Cordova + Ionic + AngularJS 开发你的 App

- - SegmentFault 最新的文章
本文是一篇关于我本人在使用 Cordova + Ionic 以及 AngularJS 开发移动App的过程中的经验的总结,它不是一篇基础入门教程,而是和大家探讨一下关于如何更好的使用这些技术开发一个更好的App,文章会每天抽一点时间完成,如果您有什么问题或者想与我交流的经验,欢迎随时在本文下方评论或者邮件给我:54778899 [at] qq.com.

完整

- None - 韩寒
在年29的白天,钱云会的手表视频被曝光了. 很巧,我也有一块和钱村长一样的手表,是我父亲在我今年生日的时候在上海国际赛车场里送给我的. 但是我没有怎么用过它,所以和我约会的姑娘大可放心. 我有一个朋友质疑说,为什么视频里先出现了老钱的脸,是否太欲盖弥彰了. 这个我倒是可以来解释一下,因为我这款手表的摄像头在表盘的十二点钟位置,而开摄像头的按键在右边的表盘侧面上,按压两秒就打开摄像头,这个时候摄像头的小灯会发出蓝光,5秒钟以后熄灭,表示录制开始.

HDFS数据完整性

- - CSDN博客推荐文章
为了保证数据的完整性,一般采用数据校验技术:. 2、md5,sha1等校验技术. 3、CRC-32循环冗余校验技术. 1、HDFS以透明方式校验所有写入的数据,可以通过io.bytes.per.checksum属性设置,字节数默认是512 字节,创建一个单独的校验和,如果节点检测数据错误,就会报 CheckSumException异常.

关于“学习”的完整过程

- daniel - 左岸读书_blog
原文:http://iamwill.net/about-study/. 学习是怎样的一个过程,怎样才算是完全掌握了一门学问、知识、技能呢. 作为一个生存于如斯万变时代下的一个个体,“学习”是生存的基本技能. 学习有两个目的,一是学习专业知识,也就是我们在学校里、在工作中学习、领悟到的东西,目的是形成自己的专业知识,有能力养活自己;二是形成自己的人生观、价值观,这个在中国的学校里几乎学不到,这个要靠我们自己的领会,跟有思想的人学习礼仪、沟通,让我们在生活中跟人交流相处更容易,也形成自己的人格.

Russell Peters纽约表演完整版

- 刘 - 囧片王
他能用带着各种种族口音的英语把各个种族的特点都嘲笑一番,更厉害的是,当他在损人家的时候,被损的还笑得要死,继续为他的单口相声买单. Russell Peters的其他爆笑单口相声. 感谢aimeibuai来自囧饭王的推荐.

完整B2C网站的设计过程

- 马克叔叔 - 互联网的那点事
以前写过一篇类似的文章,不过因为工作的原因相对写的比较简单,这次从产品的角度重新整理一下以往工作中的一些经验,算是对自己的一个阶段的总结. 作为一个产品的发起人,你可能是公司的CEO,也可能是一名产品经理,甚至会是一个普通的创业者,不论你的职位是什么,想做好一个网站就必须对它的目标人群有充分的认识,清楚的明白我的主要消费人群需要什么.

发现拥有不完整的美

- Zane - XJP的碎碎念
刚开始跟身边朋友推荐Kik、Whatsapp,他们总会问说这跟QQ有什么区别,而且还没有QQ的功能更强大. 最近也不断有朋友开始尝试陌生人社交应用,例如微信、陌陌、几米帮你找找谁在你附近,也不断有人会问为什么要用这个. 要找人问朋友直接讲电话不就好了. 对于这样的提问我总是感到无能为力,因为我不能像做数学推理一样最后告诉他一个绝对准确的结论,无关于说服谁.