<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>绿色记忆 &#187; IOS</title>
	<atom:link href="https://blog.gmem.cc/category/work/mobile/ios/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.gmem.cc</link>
	<description></description>
	<lastBuildDate>Fri, 03 Apr 2026 04:13:36 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.14</generator>
	<item>
		<title>PhoneGap学习笔记</title>
		<link>https://blog.gmem.cc/phonegap-study-note</link>
		<comments>https://blog.gmem.cc/phonegap-study-note#comments</comments>
		<pubDate>Tue, 01 Dec 2015 07:21:52 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Cordova]]></category>

		<guid isPermaLink="false">https://blog.gmem.cc/?p=9504</guid>
		<description><![CDATA[<p>由于PhoneGap和Apache Cordova在底层上的一致性，本文主要讨论PhoneGap提供的额外工具，其他主题请参考： 基于Apache Cordova开发移动应用程序 PhoneGap简介 PhoneGap是什么 一个框架，支持通过标准的基于JavaScript的API，来开发跨平台的移动应用。PhoneGap同时支持基于Web、基于Native两种风格的混合应用，它通过联合使用Native元素和Web元素，来达到更加Native的look and feel。通过PhoneGap底层的Apache Cordova框架，我们可以使用很多设备的原生特性，例如GPS、罗盘、摄像头。 基于PhoneGap的混合应用有以下额外的特点： 不能完整调用原生API：只有受限的、通用的基础API被Cordova框架支持 平台差异化不足，应用界面长得差不多 PhoneGap与Apache Cordova的关系 后者是PhoneGap的底层框架，PhoneGap是后者的一个distribution。两者提供的命令行工具很类似，使用一套插件体系。PhoneGap提供了一些额外功能，包括： PhoneGap Developer App PhoneGap Desktop App <a class="read-more" href="https://blog.gmem.cc/phonegap-study-note">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/phonegap-study-note">PhoneGap学习笔记</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><p>由于PhoneGap和Apache Cordova在底层上的一致性，本文主要讨论PhoneGap提供的额外工具，其他主题请参考：</p>
<ol>
<li><a href="/mobile-app-dev-with-apache-cordova">基于Apache Cordova开发移动应用程序</a></li>
</ol>
<div class="blog_h1"><span class="graybg">PhoneGap简介</span></div>
<div class="blog_h2"><span class="graybg">PhoneGap是什么</span></div>
<p>一个框架，支持通过标准的基于JavaScript的API，来开发跨平台的移动应用。PhoneGap同时支持<span style="background-color: #c0c0c0;">基于Web、基于Native</span>两种风格的混合应用，它通过联合使用Native元素和Web元素，来达到更加Native的look and feel。通过PhoneGap底层的Apache Cordova框架，我们可以使用很多设备的原生特性，例如GPS、罗盘、摄像头。</p>
<p>基于PhoneGap的混合应用有以下额外的特点：</p>
<ol>
<li>不能完整调用原生API：只有受限的、通用的基础API被Cordova框架支持</li>
<li>平台差异化不足，应用界面长得差不多</li>
</ol>
<div class="blog_h2"><span class="graybg">PhoneGap与Apache Cordova的关系</span></div>
<p>后者是PhoneGap的底层框架，PhoneGap是后者的一个distribution。两者提供的<span style="background-color: #c0c0c0;">命令行工具很类似，使用一套插件体系</span>。PhoneGap提供了一些额外功能，包括：</p>
<ol>
<li>PhoneGap Developer App</li>
<li>PhoneGap Desktop App</li>
<li>PhoneGap Enterprise</li>
<li>云端构建功能</li>
</ol>
<div class="blog_h1"><span class="graybg">安装PhoneGap和设备端工具</span></div>
<div class="blog_h2"><span class="graybg">命令行工具（CLI）</span></div>
<p>PhoneGap依赖于Node.js、NPM（Node.js目前自带）、git，准备好后，运行：</p>
<pre class="crayon-plain-tag">npm install -g phonegap@latest</pre>
<p>安装结束后，即可运行命令<pre class="crayon-plain-tag">phonegap </pre> ，来执行工程<span style="background-color: #c0c0c0;">创建、构建、安装、启动HTTP服务</span>等功能。除了使用命令行工具外，PhoneGap还提供了<a href="http://build.phonegap.com/">云端构建服务</a>，简化构建、App打包流程。</p>
<div class="blog_h2"><span class="graybg">桌面工具（PhoneGap Desktop App）</span></div>
<p>PhoneGap为Windows、Mac OS X提供了图形化界面，使用它可以方便的创建新的PhoneGap应用。可以到<a href="https://github.com/phonegap/phonegap-app-desktop/releases/download/0.2.0/PhoneGapSetup-win32.exe">这里</a>下载Windows的安装包。</p>
<p>该工具价值不大，使用PhoneGap CLI可以很容易的代替之。</p>
<div class="blog_h2"><span class="graybg"><a id="device-tool"></a>设备端工具</span></div>
<p>PhoneGap提供了一个移动APP——<a href="http://app.phonegap.com/">PhoneGap Developer App</a>（以下简称PGDA），可以方便的在设备上<span style="background-color: #c0c0c0;">预览、测试</span>PhoneGap应用。不需要<span style="background-color: #c0c0c0;">任何插件的支持或者编译步骤</span>，该APP就可以支持设备Native特性的访问。</p>
<p>该APP有安卓、IOS、WP三个版本，可以到对应的商店下载安装。</p>
<div class="blog_h3"><span class="graybg">定制PGDA</span></div>
<p>PGDA本质上就是一个Phonegap应用程序，只是它具有从远程服务器上同步最新Web代码的能力。PGDA默认自带了Cordova内置插件，如果你要使用第三方插件，必须自己构建PGDA。</p>
<p>PGDA的源码托管在：<a href="https://github.com/phonegap/phonegap-app-developer">https://github.com/phonegap/phonegap-app-developer</a></p>
<p>下载源码后，可以参考如下方式添加新插件支持，并构建（以Android为例）：</p>
<pre class="crayon-plain-tag">cd phonegap-app-developer
# 添加NFC插件的支持
cordova plugin add phonegap-nfc
#构建Android平台
cordova build android</pre>
<p>构建完毕后，文件platforms\android\build\outputs\apk\android-debug.apk即为最新的PGDA安装包，安装到设备即可。 </p>
<div class="blog_h1"><span class="graybg">Hello World!</span></div>
<p>打开PhoneGap桌面版本，点击左侧的+号，即可创建新的PhoneGap应用。输入路径、名称、ID后，即可创建工程。新创建的工程的结构如下：</p>
<table class="fixed-word-wrap" style="width: 100%;" border="1" cellspacing="0" cellpadding="5">
<thead>
<tr>
<td style="width: 25%; text-align: center;">目录/文件</td>
<td style="text-align: center;">说明 </td>
</tr>
</thead>
<tbody>
<tr>
<td>.cordova</td>
<td>存放Apache Cordova相关的文件 </td>
</tr>
<tr>
<td>hooks</td>
<td rowspan="5">这些目录/文件与Apache Cordova工程同名目录/文件的含义相同</td>
</tr>
<tr>
<td>platforms</td>
</tr>
<tr>
<td>plugins</td>
</tr>
<tr>
<td>www</td>
</tr>
<tr>
<td>config.xml</td>
</tr>
</tbody>
</table>
<p>亦可导入既有的PhoneGap应用，Apache Cordova应用也是支持的，可以导入。</p>
<p>点击项目右侧的右侧的运行按钮，会启动一个HTTP服务，侦听3000端口。</p>
<p>打开移动设备，点击PGDA图标，输入上述HTTP服务的地址和端口，点击Connect，看到<span style="background-color: #c0c0c0;">DEVICE IS READY</span>字样，说明设备和HTTP服务器连接成功。在此设备界面上：</p>
<ol>
<li>四指轻触：刷新视图</li>
<li>三指轻触：回到PGDA主界面</li>
</ol>
<p>现在，可以打开<pre class="crayon-plain-tag">www/index.html</pre> 下的文件进行编辑，例如我们可以修改<pre class="crayon-plain-tag">&lt;h1&gt;PhoneGap&lt;/h1&gt;</pre>中的文本。其结果将很快的反映到移动设备上。</p>
<div class="blog_h1"><span class="graybg">PhoneGap CLI详解</span></div>
<p>命令格式：<pre class="crayon-plain-tag">phonegap [子命令] [选项]</pre> </p>
<div class="blog_h3">全局命令</div>
<table class=" fixed-word-wrap full-width">
<thead>
<tr>
<td style="width: 20%; text-align: center;">命令</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>create</td>
<td>
<pre class="crayon-plain-tag">phonegap create [options] &lt;path&gt; [id [name [config]]]</pre></p>
<p>创建新的PhoneGap工程：<br />path 在此目录创建工程<br />id 作为应用程序唯一标识的包名称<br />name 应用程序的名称<br />config JSON格式的配置信息，将被存放到.cordova/config.json目录<br />options<br />　--template &lt;name&gt; 从既有的应用模板创建，template命令可以管理模板<br />　--copy-from &lt;path&gt; 从既有的工程复制并创建<br />　--link-to &lt;path&gt; 链接到既有的www目录而不复制</p>
<p>举例：</p>
<p><pre class="crayon-plain-tag">phonegap create project-dir cc.gmem.phonegap.study PhonegpStudy</pre>
</td>
</tr>
<tr>
<td>help</td>
<td>显示帮助信息</td>
</tr>
</tbody>
</table>
<div class="blog_h3"><span class="graybg">工程命令</span></div>
<table class=" fixed-word-wrap full-width">
<thead>
<tr>
<td style="width: 20%; text-align: center;"><span style="font-weight: normal; line-height: 19px;">命令</span></td>
<td style="text-align: center;"><span style="font-weight: normal; line-height: 19px;">说明</span></td>
</tr>
</thead>
<tbody>
<tr>
<td><span style="line-height: 19px;">run</span></td>
<td><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px;"><pre class="crayon-plain-tag">phonegap run [&lt;platforms&gt;] [options] [-- [platform options]]</pre> <br />准备、构建、安装应用程序到指定平台，如果不提供platforms参数，则对所有已添加的平台执行<br />options<br /></span></span>　--device 安装到设备<br />　--emulator 安装到模拟器<br />　--target &lt;id&gt; 安装到指定的目标<br />　--debug 以Debug模式构建（默认）<br />　--release 以Release模式构建<br />　--nobuild 跳过构建，直接安装</td>
</tr>
<tr>
<td><span style="line-height: 19px;">platform</span></td>
<td><span style="line-height: 19px;">管理平台，支持add、remove、update、check、list操作，与Cordova命令基本一致</span></td>
</tr>
<tr>
<td><span style="line-height: 19px;">plugin</span></td>
<td><span style="line-height: 19px;">管理插件，支持add、remove、list等操作，与Cordova命令基本一致</span></td>
</tr>
<tr>
<td><span style="line-height: 19px;">template</span></td>
<td>
<pre class="crayon-plain-tag"># 列出可用模板
phonegap template list</pre></p>
<p>从既有工程创建模板，或者列出可用模板</p>
</td>
</tr>
<tr>
<td><span style="line-height: 19px;">info</span></td>
<td><span style="line-height: 19px;">显示工程的相关信息 ，与Cordova命令基本一致</span></td>
</tr>
<tr>
<td><span style="line-height: 19px;">serve</span></td>
<td><span style="line-height: 19px;"><pre class="crayon-plain-tag">phonegap serve [options]</pre> <br />作为本地Web应用程序运行，PGDA可以连接到这样的Web服务：<br />options<br />　--port, -p &lt;n&gt; HTTP端口，默认3000<br />　--autoreload 当服务器端文件发生变化时，自动刷新PGDA，默认true<br />　--no-autoreload 禁止上述刷新<br />　--browser 启用桌面浏览器支持，默认false<br /></span></td>
</tr>
<tr>
<td><span style="line-height: 19px;">remote</span></td>
<td><pre class="crayon-plain-tag">phonegap remote [command]</pre> <br />在PhoneGap云端构建服务上执行命令：<br />command<br />　login　登录到云端构建<br />　logout 从云端构建退出登录<br />　build &lt;platform&gt; 构建指定的平台<br />　install &lt;platform&gt; 安装指定的平台<br />　run &lt;platform&gt; 构建并安装指定的平台</td>
</tr>
<tr>
<td><span style="line-height: 19px;">prepare</span></td>
<td rowspan="3"><span style="line-height: 19px;">与对应的Cordova命令基本一致</span></td>
</tr>
<tr>
<td><span style="line-height: 19px;">compile</span></td>
</tr>
<tr>
<td><span style="line-height: 19px;">emulate</span></td>
</tr>
<tr>
<td><span style="line-height: 19px;">cordova</span></td>
<td><span style="line-height: 19px;">执行指定的Cordova命令</span></td>
</tr>
</tbody>
</table>
<div class="blog_h1"><span class="graybg">PhoneGap云构建服务</span></div>
<p>利用Adobe提供的PhoneGap云端服务，只需要上传PhoneGap应用程序的资产文件（HTML、CSS、JavaScript），后续的构建工作可以在云端完成。使用云构建服务，可以：</p>
<ol>
<li>避免本地维护各套平台SDK、甚至安装多套操作系统的麻烦</li>
<li>加快开发周期，在云端可以更快的构建，并且构建结果可以推送到测试人员预安装的App中</li>
</ol>
<p>云构建服务分为免费、收费版本，免费版本仅支持一个私有（闭源、商业）App。</p>
<div class="blog_h1"><span class="graybg">常见问题</span></div>
<div class="blog_h3"><span class="graybg">PhoneGap Developer App不自动重新加载</span></div>
<p>自动重新加载时，PhoneGap CLI会在控制台上打印信息：<pre class="crayon-plain-tag">[phonegap] 200 /__api__/autoreload</pre> </p>
<p>自动重新加载的前提条件是，页面引用cordova的JavaScript文件：</p>
<pre class="crayon-plain-tag">&lt;script type="text/javascript" src="cordova.js"&gt;&lt;/script&gt;</pre>
<p>此外，某些版本上的模拟器不能正常reload，可能是兼容性问题。</p>
<div class="blog_h3"><span class="graybg">iOS6上PhoneGap Developer App报错：404 /__api__/appzip</span></div>
<p>我的手机是越狱后的iOS 6.1.2，在AppStore下载的PGDA 1.5.12，无法连接到通过<pre class="crayon-plain-tag">phonegap serve</pre> 启动的服务器。 </p>
<p>到<a href="https://github.com/phonegap/phonegap-app-developer/tree/master/resources/release/ios">GitHub</a>上逐个下载预构建版本并安装测试，发现：</p>
<ol>
<li>1.5.x：全部不能使用</li>
<li>1.4.0：可以连接但无法自动重新加载</li>
<li>1.3.0：能够连接，也可以autoreload</li>
</ol>
<p>很无语……现在安装1.3.0正常使用。</p>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/phonegap-study-note">PhoneGap学习笔记</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/phonegap-study-note/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于Apache Cordova开发移动应用程序</title>
		<link>https://blog.gmem.cc/mobile-app-dev-with-apache-cordova</link>
		<comments>https://blog.gmem.cc/mobile-app-dev-with-apache-cordova#comments</comments>
		<pubDate>Mon, 09 Nov 2015 09:20:41 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Cordova]]></category>

		<guid isPermaLink="false">https://blog.gmem.cc/?p=9730</guid>
		<description><![CDATA[<p>基础知识 名词术语 目标平台：本文中会反复出现该名词，目标平台是指移动操作系统+移动应用SDK构成的移动应用支撑环境。有时也称作移动平台，或简称平台 构建平台：在其上运行Cordova工具，生成目标平台应用程序的宿主操作系统 PhoneGap：目前作为Apache Cordova的一个发行版，它们的命令行非常相似。PhoneGap提供了一些更高级的组件，例如云端构建、设备端工具（PhoneGap Developer App） 移动应用开发技术的选型 可以选择三种方式来开发移动应用，它们各有特点： 原生（Native）应用 为特定的设备、操作系统构建。需要熟悉设备SDK，甚至特殊的开发语言：Objective-C/Swift (iOS)；Java (Android)；C# (Windows) 安装到设备，作为本地程序运行 使用原生的API和控件 通常必须经过应用市场的验证才能被客户使用 可以离线使用 性能优秀 纯Web应用 在任何移动浏览器中运行 <a class="read-more" href="https://blog.gmem.cc/mobile-app-dev-with-apache-cordova">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/mobile-app-dev-with-apache-cordova">基于Apache Cordova开发移动应用程序</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><div class="blog_h1"><span class="graybg">基础知识</span></div>
<div class="blog_h2"><span class="graybg">名词术语</span></div>
<ol>
<li>目标平台：本文中会反复出现该名词，目标平台是指<span style="background-color: #c0c0c0;">移动操作系统+移动应用SDK</span>构成的移动应用支撑环境。有时也称作移动平台，或简称平台</li>
<li>构建平台：在其上运行Cordova工具，生成目标平台应用程序的宿主操作系统</li>
<li>PhoneGap：目前作为Apache Cordova的一个发行版，它们的命令行非常相似。PhoneGap提供了一些更高级的组件，例如云端构建、设备端工具（PhoneGap Developer App）</li>
</ol>
<div class="blog_h2"><span class="graybg">移动应用开发技术的选型</span></div>
<p>可以选择三种方式来开发移动应用，它们各有特点：</p>
<div class="blog_h3"><span class="graybg">原生（Native）应用</span></div>
<ol>
<li>为特定的设备、操作系统构建。需要熟悉设备SDK，甚至特殊的开发语言：Objective-C/Swift (iOS)；Java (Android)；C# (Windows)</li>
<li>安装到设备，作为本地程序运行</li>
<li>使用原生的API和控件</li>
<li>通常必须经过应用市场的验证才能被客户使用</li>
<li>可以离线使用</li>
<li>性能优秀</li>
</ol>
<div class="blog_h3"><span class="graybg">纯Web应用</span></div>
<ol>
<li>在任何移动浏览器中运行</li>
<li>支持受限的使用设备特性</li>
<li>基于标准的Web技术构建，包括HTML、CSS、JavaScript</li>
<li>需要支持多种屏幕尺寸</li>
<li>需要Web服务器的支撑，不支持离线使用</li>
<li>性能较差</li>
</ol>
<div class="blog_h3"><span class="graybg">混合（Hybrid）应用</span></div>
<p>所谓混合应用，就是结合了前两者的特性和优势的应用，混合应用可以分为两种风格：</p>
<ol>
<li>基于Web的混合应用（Web hybrid mobile apps）：APP运行在一个很薄的<span style="background-color: #c0c0c0;">Native容器+WebView</span>中，该容器仅作为访问Native特性的桥梁，所有UI组件均基于Web技术构建</li>
<li>基于Native的混合应用（Native hybrid mobile apps）：包含很多的Native控件，以及1-N个WebView。常常<span style="background-color: #c0c0c0;">使用Native控件做导航、并在提供应用内容的WebView之间进行切换</span></li>
</ol>
<p>混合应用具有以下特性：</p>
<ol>
<li>安装到设备，作为本地程序运行</li>
<li>应用逻辑主要在WebView（嵌入的Web浏览器）中运行</li>
<li>大部分代码是跨平台的</li>
<li>支持访问原生特性</li>
<li>由于应用内容主要使用基于设备内置浏览器引擎，因此性能比起原生应用差</li>
</ol>
<div class="blog_h1"><span class="graybg">Apache Cordova简介</span></div>
<p>Apache Cordova是一个开源移动应用开发框架，它允许你使用标准的Web技术——HTML5、CSS3、JavaScript ——来进行跨平台开发，避免使用各移动平台Native的编程语言和SDK。基于Cordova的应用程序被包装在各平台的Wrapper中，使用标准兼容的API访问设备传感器、数据和其它Native特性。</p>
<div class="blog_h2"><span class="graybg">基本组件</span></div>
<p>Apache Cordova 工程依赖于一个命名为<span style="background-color: #c0c0c0;">config.xml</span>的配置文件，该配置文件影响应用程序的工作方式（例如是否对横屏做出响应）。</p>
<p>应用程序本身实现为<span style="background-color: #c0c0c0;">网页</span>，默认情况下是本地的一个index.html文件，该文件可能引用任何Web资源，例如JavaScript、CSS。应用程序被包装在Native的Wrapper中，作为WebView运行。该WebView作为更大的混合（Hybrid ）应用的一个组件，或者占据整个UI。</p>
<p><span style="background-color: #c0c0c0;">插件接口（plugin interface ）</span>允许Cordova和Native组件之间进行通信，插件接口以JavaScript的形式提供，从而允许在网页上调用Native代码。理想情况下，各平台的API应该一致，在3.0中，官方插件提供标准化的设备API，而<a href="http://plugins.cordova.io/">第三方插件</a>可能提供一些特定于特殊平台的API。Cordova官方提供了自定义插件的<a href="https://cordova.apache.org/docs/en/latest/guide/hybrid/plugins/index.html">开发文档</a>。</p>
<p>从3.0开始，新创建的Cordova工程默认不包含任何插件，所有插件都需要手工添加。</p>
<div id="cordova-workflow" class="blog_h2"><span class="graybg">开发工作流（Workflow）</span></div>
<p>Cordova 应用的开发工作流有两种：</p>
<ol>
<li>以Cordova CLI为中心跨平台工作流：如果需要应用在尽可能多的平台上运行，可以使用这种方式，该方式需要很少的平台特定开发工作量。CLI是3.0引入的，可以同时为多个平台构建工程的工具，它是Cordova跨平台工作流的核心。CLI会<span style="background-color: #c0c0c0;">创建Cordova工程的初始结构、把Web资产文件拷贝到各平台的子目录下、对各平台进行必要的配置，然后运行脚本生成二进制程序</span>。CLI也提供了为应用添加插件的公共接口</li>
<li>以平台为中心的工作流：如果需要构建特定单个平台的应用，以及需要在底层基于平台SDK对代码进行修改，可以使用该方式。典型的例子是开发Native-based混合应用，需要把WebView和其他Native组件集成时。使用这种方式开发时，可以通过<span style="background-color: #c0c0c0;">Plugman</span>来添加插件</li>
</ol>
<p>推荐以第1种方式开始，使用CLI创建Cordova工程，在<span style="background-color: #c0c0c0;">必要时切换</span>到第2种方式。针对平台的低级别Shell工具可以在工程的<pre class="crayon-plain-tag">platforms/*/cordova</pre> 目录下找到（其中*代表平台名称）。<span style="background-color: #c0c0c0;">一旦切换，就不能返回</span>，因为CLI管理的跨平台源代码集会在每次构建时被覆盖。为了保护你修改过的代码，必须使用平台特定的Shell工具，这些Shell工具忽略跨平台代码而依赖于平台特定的代码。</p>
<div class="blog_h1"><span class="graybg">基于CLI的跨平台工作流</span></div>
<p>使用Cordova的命令行接口（CLI），可以完成新工程的创建、针对各平台进行构建、并部署到设备（或模拟器）中运行。</p>
<p>在安装和使用CLI前，必须下载和安装相关目标平台的SDK和相关工具，如果不安装，在调用CLI进行应用构建时会收到错误提示，例如：</p>
<pre class="crayon-plain-tag">#没有安装完整Android SDK机器上的报错信息
Running command: cmd "/s /c "...\cordova-study\platforms\android\cordova\build.bat""
[Error: Please install Android target: "android-22".

Hint: Open the SDK manager by running: D:\Android\sdk\tools\android.BAT
You will require:
1. "SDK Platform" for android-22
2. "Android SDK Platform-tools (latest)
3. "Android SDK Build-tools" (latest)]
ERROR building one of the platforms: Error: cmd: Command failed with exit code 2
You may not have the required environment or OS to build this project</pre>
<p>CLI支持的<span style="background-color: #c0c0c0;">目标平台（构建平台）</span>包括：</p>
<ol>
<li>iOS（Mac）</li>
<li>Android (Mac, Linux, Windows)</li>
<li>BlackBerry 10 (Mac, Linux, Windows)</li>
<li>Windows Phone 8 (Windows)</li>
</ol>
<p>可以看到如果要支持全部主要的目标平台，你需要在不同操作系统上运行CLI命令，这意味着你应该使用代码库（SVN/Git）来管理工程。</p>
<div class="blog_h2"><span class="graybg">安装Cordova CLI</span></div>
<ol>
<li><a href="/node-js-faq">安装Node.js</a></li>
<li><a href="https://git-scm.com/downloads">安装Git客户端</a></li>
<li>通过npm命令安装cordova模块：<br />
<pre class="crayon-plain-tag"># 安装Cordova为全局模块
npm install -g cordova
#安装特定版本的Cordova
npm install -g cordova@3.1.0-0.2.0

#更新Cordova
npm update -g cordova

#显示版本信息
cordova -v</pre>
</li>
</ol>
<div class="blog_h2"><span class="graybg">创建Cordova工程</span></div>
<p>执行下面的命令创建工程：</p>
<pre class="crayon-plain-tag">pushd D:\JavaScript\projects\cordova\5.4.1
# cordova-study在当前目录下创建的子目录，作为工程文件的容器
# cc.gmem.study.cordova 域名反转的包名，可能被生成的外部文件引用，例如Android包名
# CordovaStudy 应用程序的标题
# 第2/3个参数可以在config.xml中手工修改
cordova create cordova-study cc.gmem.study.cordova CordovaStudy</pre>
<p>命令执行完毕后，生成如下目录结构： </p>
<table class="fixed-word-wrap" style="width: 100%;" border="1" cellspacing="0" cellpadding="5">
<thead>
<tr>
<td style="width: 25%; text-align: center;">目录/文件</td>
<td style="text-align: center;">说明 </td>
</tr>
</thead>
<tbody>
<tr>
<td>hooks</td>
<td>Cordova钩子脚本的存放目录</td>
</tr>
<tr>
<td>platforms</td>
<td>生成的平台特定的文件，包括工程代码和元数据。基于CLI的跨平台工作流进行开发时，应该避免修改此目录下的任何文件</td>
</tr>
<tr>
<td>plugins</td>
<td>应用程序使用的插件目录</td>
</tr>
<tr>
<td>merges</td>
<td>用于合并到各平台assets/www中的文件，特定于平台的文件，按照www的结构，在此目录下存放，在构建时会自动合并</td>
</tr>
<tr>
<td>www</td>
<td>存放应用程序的主页面（index.html），以及css、js、img等Web资源。这些资产内容会<span style="background-color: #c0c0c0;">存放在设备的本地文件系统，而不是远程Web服务器</span>上。开发Cordova应用的主要工作在此目录下进行</td>
</tr>
<tr>
<td>config.xml</td>
<td>包含了用于生成和分发应用程序的重要元数据</td>
</tr>
</tbody>
</table>
<div class="blog_h2"><span class="graybg">添加目标平台支持</span></div>
<p>运行下面的命令添加对特定平台的支持：</p>
<pre class="crayon-plain-tag">#添加Android平台的支持
cordova platform add android
#输出如下：
Running command: cmd "/s /c "...\create.bat ...\cordova-study\platforms\android cc.gmem.study.cordova CordovaStudy --cli""
Creating Cordova project for the Android platform:
        #创建目标平台工程特定的文件
        Path: platforms\android
        Package: cc.gmem.study.cordova
        Name: CordovaStudy
        Activity: MainActivity
        Android target: android-22
Copying template files...
Android project created with cordova-android@4.1.1
#安装插件
Discovered plugin "cordova-plugin-whitelist" in config.xml. Installing to the project
Fetching plugin "cordova-plugin-whitelist@1" via npm
Installing "cordova-plugin-whitelist" for android


#添加iOS平台的支持，需要在安装了iOS SDK的Mac OS X上执行
cordova platform add ios
#添加Windows Phone 8平台的支持，需要在Windows上运行
cordova platform add wp8


#下面的命令示例了如何移除平台的支持
cordova platform remove blackberry10

#添加指定版本的cordova平台支持，并保存到config.xml中
cordova platform add android@3.7.0 --save</pre>
<p>运行上述命令后，Cordova工程的platforms、plugins子目录出现一些下载/生成的文件：</p>
<table class="fixed-word-wrap" style="width: 100%;" border="1" cellspacing="0" cellpadding="5">
<thead>
<tr>
<td style="width: 140px; text-align: center;">目录</td>
<td style="width: 100px; text-align: center;">子目录</td>
<td style="text-align: center;">说明 </td>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="7">platforms/android      </td>
<td>.</td>
<td>当前目录包含了一个完整的Android工程，可以导入到Android Studio或者ADT中</td>
</tr>
<tr>
<td>cordova</td>
<td>特定于Android平台的Shell工具，可以完成Android平台应用的构建、清理、运行</td>
</tr>
<tr>
<td>CordovaLib</td>
<td>一个Android工程，包含了作为Android库的Cordova源代码</td>
</tr>
<tr>
<td>assets</td>
<td rowspan="4">
<p>遵循Android工程的默认用途</p>
<p>其中：</p>
<ol>
<li>assets/www包含了Cordova应用的所有Web资源文件，包括HTML、CSS、JS等。<span style="background-color: #c0c0c0;">Cordova工程中的www目录中的内容全部复制一份</span>覆盖到该目录。插件的Web资源也拷贝并覆盖到plugins子目录</li>
<li>src目录包含自动生成的一个Activity源码、已经拷贝过来的插件源代码</li>
</ol>
</td>
</tr>
<tr>
<td>src</td>
</tr>
<tr>
<td>libs</td>
</tr>
<tr>
<td>res</td>
</tr>
<tr>
<td>plugins</td>
<td colspan="2">存放下载的对应各目标平台的插件源代码、文档</td>
</tr>
</tbody>
</table>
<p><a href="#cordova-workflow">前面</a>我们说过，创建新工程可以从CLI命令行开始，在必要时切换到特定平台的开发工作中去。在此，就可以进行切换了：只需要把platforms子目录导入到Eclipse、XCode等IDE即可，然后以IDE为中心完成后续开发。</p>
<p>如果继续执行以CLI为中心的工作流，则需要继续了解下面的小节。</p>
<div class="blog_h2"><span class="graybg">构建应用</span></div>
<p>执行下面的命令可以构建应用程序的二进制文件并打包：</p>
<pre class="crayon-plain-tag"># 构建所有平台
cordova build
# 构建特定平台
cordova build ios</pre>
<p>上述build命令实际上包含了两个步骤： </p>
<pre class="crayon-plain-tag"># 准备阶段，会把Cordova源码拷贝、合并到平台的对应目录中
# 一旦执行完该命令，就可以用特定平台提供的SDK进行修改、编译
cordova prepare ios
# 编译
cordova compile ios</pre>
<div class="blog_h2"><span class="graybg">在设备上测试应用</span></div>
<p>运行下面的命令重新构建特定平台的应用，并部署到模拟器中：</p>
<pre class="crayon-plain-tag"># 运行下面的命令后，Cordova会自动启动模拟器，并把APK安装到上面
# 如果有模拟器正在运行，则使用既有的模拟器
cordova emulate android
# APK安装完毕后，将自动运行</pre>
<p> 或者，将启用了调试模式的手机连接到当前计算机，然后运行：</p>
<pre class="crayon-plain-tag">cordova run android</pre>
<div class="blog_h2"><span class="graybg">添加插件支持</span></div>
<p>你可以使用Web技术修改Cordova生成的应用骨架，来开发漂亮的页面。但是如果<span style="background-color: #c0c0c0;">想使用设备底层特性，则必须添加插件</span>，利用插件可以访问核心Cordova API。第三方/自己开发的插件可以用来访问特殊的设备特性，要访问通用设备特性使用Cordova提供的的插件就足够了。官方插件和第三方插件的列表位于<a href="http://cordova.apache.org/plugins/">http://cordova.apache.org/plugins/</a>。</p>
<p>下面的命令用来搜索插件：</p>
<pre class="crayon-plain-tag">#同时包含bar和code的插件
cordova plugin search bar code</pre>
<p>下面的命令用来列出当前工程已添加的插件：</p>
<pre class="crayon-plain-tag">cordova plugin ls</pre>
<p>下面的命令用来移除已经添加的插件：</p>
<pre class="crayon-plain-tag">cordova plugin rm cordova-plugin-console</pre>
<p>下面的命令用来给应用程序添加插件：</p>
<pre class="crayon-plain-tag">#依据插件ID添加
cordova plugin add plugin-id
#添加特定版本的插件
cordova plugin add plugin-id@latest
cordova plugin add plugin-id@1.2.0

# 设备基本特性
cordova plugin add cordova-plugin-device
# 网络连接信息
cordova plugin add cordova-plugin-network-information
# 电池状态
cordova plugin add cordova-plugin-battery-status
# 加速度计
cordova plugin add cordova-plugin-device-motion
# 横屏切换
cordova plugin add cordova-plugin-device-orientation
# 地理位置信息
cordova plugin add cordova-plugin-geolocation
# 摄像头
cordova plugin add cordova-plugin-camera
# 媒体截屏
cordova plugin add cordova-plugin-media-capture
# 媒体回放
cordova plugin add cordova-plugin-media
# 访问设备或网络上的文件
cordova plugin add cordova-plugin-file
cordova plugin add cordova-plugin-file-transfer
# 通过振动或者对话框通知用户
cordova plugin add cordova-plugin-dialogs
cordova plugin add cordova-plugin-vibration
# 访问通讯录
cordova plugin add cordova-plugin-contacts
# 国际化
cordova plugin add cordova-plugin-globalization
# 启动画面支持
cordova plugin add cordova-plugin-splashscreen
# 打开新的应用内浏览器窗口
cordova plugin add cordova-plugin-inappbrowser
# 调试控制台
cordova plugin add cordova-plugin-console</pre>
<p>CLI根据需要为各平台添加插件代码。Plugman可以为单个平台添加插件支持。 </p>
<p>如果插件没有在默认源（registry.cordova.io ）注册，通过下面的命令添加：</p>
<pre class="crayon-plain-tag"># 从Git的master分支下载插件
cordova plugin add https://github.com/someone/aplugin.git
# 从特定标记或者分支下载插件
cordova plugin add https://github.com/someone/aplugin.git#r0.2.0
# 如果插件（以及plugin.xml）在Git仓库的子目录下，可以
cordova plugin add https://github.com/someone/aplugin.git#:/sub/dir
# 也可以从本地文件系统添加插件
cordova plugin add ../local_plugin_dir</pre>
<div class="blog_h2"><span class="graybg">利用合并进行平台差异化处理</span></div>
<p>前面提到过，在以CLI为中心的跨平台开发工作流下，不应当修改platforms子目录。那么，如果如何实现平台差异化呢？例如为不同平台提供不同的样式表.css文件，这是很合理的需求。</p>
<p>Cordova提供了一种合并机制，在工程顶级目录下，可以添加一个merges目录，其子目录是各平台的名称，例如<pre class="crayon-plain-tag">merges/android</pre> 。这些子目录的内部结构和www目录一样，在构建时，会自动覆盖www中的文件，并最终拷贝到特定平台的资产目录下。举例来说：<pre class="crayon-plain-tag">merges/android/css/index.css</pre> 会覆盖Android平台下对应的<pre class="crayon-plain-tag">www/css/index.css</pre> 文件。</p>
<p>merges中的文件如果在www下没有对应物，会直接复制到特定平台的资产目录下。</p>
<div class="blog_h2"><span class="graybg">CLI命令说明</span></div>
<p>命令格式：<pre class="crayon-plain-tag">cordova 子命令 [选项]</pre> </p>
<div class="blog_h3"><span class="graybg">通用选项</span></div>
<table class=" fixed-word-wrap full-width">
<thead>
<tr>
<td style="text-align: center;">选项</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>-v, --version</td>
<td>打印CLI版本</td>
</tr>
<tr>
<td>-d, --verbose</td>
<td>显示CLI命令的活动的详细信息</td>
</tr>
<tr>
<td>--no-update-notifier</td>
<td>禁止检查CLI的版本更新</td>
</tr>
</tbody>
</table>
<div class="blog_h3"><span class="graybg">全局命令</span></div>
<table class=" full-width fixed-word-wrap">
<thead>
<tr>
<td style="width: 25%; text-align: center;">子命令</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>create</td>
<td>创建一个新的Cordova工程</td>
</tr>
<tr>
<td>help</td>
<td>显示命令帮助：<br />
<pre class="crayon-plain-tag"># 显示run子命令的帮助信息
cordova run --help</pre>
</td>
</tr>
</tbody>
</table>
<div class="blog_h3"><span class="graybg">工程命令</span></div>
<table class=" full-width fixed-word-wrap">
<thead>
<tr>
<td style="width: 25%; text-align: center;">子命令</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>显示当前工程的详细信息，例如哪些平台被支持，添加了哪些插件</td>
</tr>
<tr>
<td>requirements</td>
<td>检查并显示指定平台的要求，例如SDK版本</td>
</tr>
<tr>
<td>platform</td>
<td>
<p>管理工程支持的平台：<br />add 添加一个平台支持<br />remove 移除平台支持<br />list 列出已经安装和可用的平台<br />update 更新特定平台使用的Cordova版本<br />check 列出支持cordova platform update的平台</p>
</td>
</tr>
<tr>
<td>plugin</td>
<td>管理工程使用的插件：<br />add 添加一个插件<br />remove 移除一个插件<br />list 列出当前安装的插件列表<br />search 从插件仓库搜索插件</td>
</tr>
<tr>
<td>prepare</td>
<td>拷贝、合并工程文件到目标平台，以备构建</td>
</tr>
<tr>
<td>compile</td>
<td>编译目标平台，命令格式：<br /><pre class="crayon-plain-tag">cordova compile [PROD] [TARGET] [EXP] [PLATS] [-- POPTS]</pre> </p>
<p>PROD：编译的变体， --debug|--release<br />TARGET：目标设备， --device|--emulator|--target=FOO<br />PLATS：目标平台，可以指定多个平台<br />POPTS：平台特定的选项 </p>
</td>
</tr>
<tr>
<td>build</td>
<td>等价于<pre class="crayon-plain-tag">cordova prepare &amp;&amp; cordova compile</pre> </td>
</tr>
<tr>
<td>clean</td>
<td>清除已经构建出的构件（artifacts）</td>
</tr>
<tr>
<td>run</td>
<td>prepare、compile，并在设备或者模拟器上运行工程：<br /> --nobuild 不进行构建<br />--debug 部署Debug版本<br />--release  部署Release版本</td>
</tr>
<tr>
<td>emulate</td>
<td>等价于<pre class="crayon-plain-tag">cordova run --emulator</pre> </td>
</tr>
<tr>
<td>serve</td>
<td>
<p>启动一个本地HTTP服务器，把工程作为Web服务使用：<br /><pre class="crayon-plain-tag">cordova serve [PORT]</pre> </p>
<p>此命令启动的服务与PhoneGap Developer App无法搭配使用，可以改用：</p>
<pre class="crayon-plain-tag">phonegap serve</pre>
</td>
</tr>
</tbody>
</table>
<div class="blog_h1"><span class="graybg">以Android平台为中心的工作流</span></div>
<p>首先，参考文章：<a href="/eclipse-adt-and-mvn-based-android-dev">基于Eclipse ADT和Maven的Android开发</a> 完整Android开发环境的搭建。
<p>由于Android平台官方的开发工具现在是Android Studio，并且基于Gradle构建，所以最好搭建好Gradle环境和Gradle的Eclipse插件。可参考文章：<a href="/gradle-study-note">Gradle学习笔记</a>。</p>
<div class="blog_h2"><span class="graybg">导入为Eclipse ADT工程</span></div>
<p>通过CLI创建Cordova工程后，一旦添加了Android平台的支持，就可以把platforms/android子目录作为工程导入到Eclipse ADT或者Android Studio。</p>
<p>以Eclipse ADT为例，操作步骤为：</p>
<ol>
<li>File ⇨ Import</li>
<li>在弹出的对话框中选择 Android ⇨ Existing Android Code Into Workspace，点击下一步</li>
<li>把Root Directory定位到Cordova工程的platforms/android目录，选择其中的两个工程，如下图：<br /><img class="aligncenter size-full wp-image-9857" src="https://blog.gmem.cc/wp-content/uploads/2015/11/import-cordova-project.jpg" alt="import-cordova-project" width="679" height="550" /></li>
<li>点击完成，工作区出现两个新的ADT工程，导入完毕</li>
</ol>
<p>这两个工程就是普通的ADT工程。其中cordovalib是cordova-android的依赖库。在cordova-android上点击右键 ⇨ Run as ⇨ Android Application，即可打包并部署到设备上运行。</p>
<p>上述方式导入的工程结构比较混乱，如果后续开发脱离Cordova进行，建议清理其中不需要的目录和文件。如果不习惯基于Gradle进行构建，可以创建或者转换为Maven工程。</p>
<div class="blog_h2"><span class="graybg">转换为Eclipse Gradle工程</span></div>
<p>安装了Gradle的Eclipse插件后，可以把platforms/android子目录转换为Gradle工程：</p>
<ol>
<li>File ⇨ Import</li>
<li>在弹出的对话框中选择 Gradle ⇨ Gradle Project，点击下一步</li>
<li>在弹出的对话框中，把Root folder定位到platforms/android子目录，然后点击右侧的Build Model按钮。Gradle从Maven仓库下载一些构件到Gradle缓存目录，完毕后显示如下画面：<img class="aligncenter size-full wp-image-10269" src="https://blog.gmem.cc/wp-content/uploads/2015/11/import-as-gradle-project.jpg" alt="import-as-gradle-project" width="653" height="716" /></li>
<li>点击完成。你可以自由的修改Eclipse工程的名称</li>
</ol>
<div class="blog_h2"><span class="graybg">转换为Eclipse Maven工程</span></div>
<p>如果习惯于使用Maven进行构建工作，可以参考下面的步骤，把platforms/android子目录转换为Maven工程：</p>
<ol>
<li>参考：<a href="/eclipse-adt-and-mvn-based-android-dev">基于Eclipse ADT和Maven的Android开发</a>创建Android的Maven工程，设工程根目录为<pre class="crayon-plain-tag">%MVN_PROJECT_ROOT%</pre> 。删除自动生成的Activity、res目录，并转换为android-maven-plugin 4.3.0标准的工程结构</li>
<li>如果使用SVN，在目录%MVN_PROJECT_ROOT% 上设置属性svn:ignore为：<br />
<pre class="crayon-plain-tag">target
bin
.*
cli</pre>
</li>
<li>通过CLI创建对应的（同名同包）Cordova工程，添加必要的插件，设工程根目录为<pre class="crayon-plain-tag">%CORDOVA_PROJECT_ROOT%</pre> </li>
<li>创建Maven工程指向Cordova工程的符号链接：<br />
<pre class="crayon-plain-tag">mklink /D %MVN_PROJECT_ROOT%\cli %CORDOVA_PROJECT_ROOT%</pre>
</li>
<li>另外创建一个Android的Maven工程“cordova-android”，project.properties中设置<pre class="crayon-plain-tag">android.library=true</pre> ，表示这是一个库工程。设工程根目录为<pre class="crayon-plain-tag">%MVN_LIB_ROOT%</pre> </li>
<li>修改<pre class="crayon-plain-tag">%MVN_PROJECT_ROOT%\pom.xml</pre> ，添加cordova-android的依赖，例如：<br />
<pre class="crayon-plain-tag">&lt;dependency&gt;
    &lt;groupId&gt;org.apache.cordova&lt;/groupId&gt;
    &lt;artifactId&gt;cordova-android&lt;/artifactId&gt;
    &lt;version&gt;4.4.1-SNAPSHOT&lt;/version&gt;
    &lt;type&gt;apklib&lt;/type&gt;
&lt;/dependency&gt;</pre>
</li>
<li>修改Cordova工程的<pre class="crayon-plain-tag">%CORDOVA_PROJECT_ROOT%\cli\platforms\android\build-extras.gradle</pre> 文件，添加以下Tasks：<br />
<pre class="crayon-plain-tag">task syncdown_src(type : Copy){
    from 'src'
    into '../../../src/main/java'
}
task syncdown_assets(type : Copy){
    from 'assets'
    into '../../../src/main/assets'
}
task syncdown_res(type : Copy){
    from 'res'
    into '../../../src/main/res'
}
task syncdown_libsrc(type : Copy){
    def dest = '../../../../cordova-android/src/main/java'
    if(file(dest).exists()){
        from 'CordovaLib/src'
        into dest
    }
}
task syncdown_manifest(type : Copy){
    from 'AndroidManifest.xml'
    into '../../../src/main'
}
task syncdown( dependsOn: [syncdown_src, syncdown_assets, syncdown_res, syncdown_libsrc, syncdown_manifest] )</pre>
</li>
<li>每当添加Cordova插件，或者修改Cordova工程中其它源码文件后，定位到<pre class="crayon-plain-tag">%MVN_PROJECT_ROOT%\cli</pre>目录，执行：<br />
<pre class="crayon-plain-tag">@echo off
call cordova prepare 
pushd platforms\android
call gradle syncdown
popd</pre></p>
<p>这会让所有修改从Cordova工程目录，同步到其Android平台子目录，然后再同步到Maven工程对应目录中。 </p>
</li>
</ol>
<div class="blog_h2"><span class="graybg">Android平台命令行工具</span></div>
<p>Android平台特定的命令行工具位于<pre class="crayon-plain-tag">platforms/android/cordova</pre> 子目录中，这些命令比Cordova CLI更有针对性，在以Android为中心的开发时，可以代替之：</p>
<pre class="crayon-plain-tag">###  构建工程  ###

#Apache Cordova CLI方式
cordova build android

#Android平台命令行工具
platforms/android/cordova/build --debug   #生成调试信息
platforms/android/cordova/build --release #对应用进行签名
#其它参数
# --ant 使用Ant进行构建
# --gradle 使用Gradle进行构建，Cordova 4.0以后的默认值
# --nobuild 不进行构建
# --prepenv 不进行构建，但是拷贝必要的构建脚本
# --versionCode=# 指定本次构建的版本号
# --minSdkVersion=# 指定本次构建要求的最低Android SDK版本代码
# --gradleArg=# 指定传递给Gradle的命令行参数
# --buildConfig 指定包含了构建配置的JSON文件


###  部署到模拟器  ###
# 需要首先配置并启动一台Android模拟器

#Apache Cordova CLI方式
cordova emulate android

#Android平台命令行工具
platforms/android/cordova/run --emulator
platforms/android/cordova/run --target=targetId #指定特定ID的模拟器
#当执行run时，默认会自动构建，可以通过参数-debug --release --nobuild控制此行为
platforms/android/cordova/run --emulator --nobuild

#通过Eclipse部署
#也可以在Eclipse中，Run As - Android Application方式部署应用



###  部署到真实设备  ###

#Apache Cordova CLI方式
cordova run android

#Android平台命令行工具
platforms/android/cordova/run --device



###  其他Android平台命令行工具  ###
platforms/android/cordova/log    #记录APP详细的运行日志
platforms/android/cordova/clean  #清理工程文件</pre>
<p>使用Android命令行build、run时，可以通过<pre class="crayon-plain-tag">--buildConfig</pre> 传入一个JSON，为构建提供配置信息。下面的JSON提供了APK签名所需的信息：</p>
<pre class="crayon-plain-tag">{
     "android": {
         "debug": {
             "keystore": "android.keystore",
             "storePassword": "android",
             "alias": "mykey1", 
             "password" : "password",
             "keystoreType": ""
         },
         "release": {
             "keystore": "android.keystore",
             "storePassword": "", //Release的密码可以不写，等待命令行提示
             "alias": "mykey2",
             "password" : "password",
             "keystoreType": ""
         }
     }
 }</pre>
<div class="blog_h2"><span class="graybg">通过Gradle执行构建</span></div>
<p>自4.0开始Gradle是Cordova默认的构建工具。</p>
<p>下表列出Cordova提供的<a href="/gradle-study-note#gradle-project-properties">Gradle工程属性</a>，可以用于定制构建： </p>
<table class=" full-width fixed-word-wrap">
<thead>
<tr>
<td style="width: 35%; text-align: center;">属性</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>cdvBuildMultipleApks</td>
<td>
<p>默认值：false，表示为所有平台生成一个通用的大的APK</p>
<p>如果设置为true，对library projects支持的每个平台（x86, ARM...）分别生成一个APK。如果工程使用大的Native库时很重要，因为Native库可能大大增加APK体积</p>
</td>
</tr>
<tr>
<td>cdvVersionCode</td>
<td>覆盖AndroidManifest.xml中的versionCode</td>
</tr>
<tr>
<td>cdvReleaseSigningPropertiesFile</td>
<td>
<p>默认值：release-signing.properties</p>
<p>包含Release版本APK签名需信息的属性文件的名称，属性文件的内容示例如下：</p>
<pre class="crayon-plain-tag">storeFile=relative/path/to/keystore.p12
storePassword=SECRET1
storeType=pkcs12
keyAlias=DebugSigningKey
keyPassword=SECRET2
#密码是可选的，如果不提供，构建时会进行交互式的提示</pre>
</td>
</tr>
<tr>
<td>cdvDebugSigningPropertiesFile</td>
<td>
<p>默认值：debug-signing.properties
<p>包含Debug版本APK签名需信息的属性文件的名称</p>
</td>
</tr>
<tr>
<td>cdvBuildToolsVersion</td>
<td>覆盖自动检测到的android.buildToolsVersion属性值。该属性由Android的Gradle插件引入</td>
</tr>
<tr>
<td>cdvCompileSdkVersion</td>
<td>覆盖自动检测到的android.compileSdkVersion属性值。该属性由Android的Gradle插件引入</td>
</tr>
</tbody>
</table>
<div class="blog_h2"><span class="graybg">扩展Gradle构建脚本</span></div>
<p>如果需要扩展Gradle构建逻辑，可以创建一个<pre class="crayon-plain-tag">build-extras.gradle</pre> 文件，并在其中编写脚本。该脚本会自动被包含在<pre class="crayon-plain-tag">build.gradle</pre> 的<span style="background-color: #c0c0c0;">首部</span>。注意避免修改build.gradle本身，该文件是自动生成的，可能被Cordova覆盖。下面是扩展脚本的一个例子：</p>
<pre class="crayon-plain-tag"># 此文件的内容被放在build.gradle的开始处

# 设置工程扩展属性
ext.cdvDebugSigningPropertiesFile = 'android-debug-keys.properties'

# 这里指定的闭包，会在build.gradle结尾处执行， 因为build.gradle的最后包含如下代码：
# if (hasProperty('postBuildExtras')) {
#     postBuildExtras()
# }
ext.postBuildExtras = {
    android.buildTypes.debug.applicationIdSuffix = '.debug'
}</pre>
<div class="blog_h2"><span class="graybg">打包和部署</span></div>
<p>有两种方式来打包Cordova应用，并部署到Android设备或者模拟器上测试：</p>
<ol>
<li>使用Maven：<pre class="crayon-plain-tag">package android:deploy android:run</pre> </li>
<li>使用ADT：在apk工程上面点击右键 Run As ⇨ Android Application</li>
</ol>
<p>注意，必须让你的设备或者模拟器链接到当前机器上。</p>
<p>这两种方式都比较慢，每次部署都需要数十秒，非常浪费时间。因此可以使用PhoneGap提供的<a href="/phonegap-study-note#device-tool">设备端工具</a>，该工具可以免部署的运行Cordova应用。</p>
<div class="blog_h1"><span class="graybg">理解Cordova HelloWorld</span></div>
<div class="blog_h3"><span class="graybg">启动</span></div>
<p>应用启动后，会自动启用一个WebView，加载config.xml中指定的起始页（默认index.html），让HTML页面占据整个屏幕空间。</p>
<p>例如，对Android平台，系统会执行MainActivity，该Activity是CordovaActivity的子类：</p>
<pre class="crayon-plain-tag">public class MainActivity extends CordovaActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // 加载HTML
        loadUrl(launchUrl);
    }
}</pre>
<div class="blog_h3"><span class="graybg">HTML和JavaScript脚本</span></div>
<pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;!-- 内容安全策略 --&gt;
        &lt;meta http-equiv="Content-Security-Policy" 
            content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; 
                     style-src 'self' 'unsafe-inline'; 
                     media-src *"&gt;
        &lt;!-- 禁止IOS的电话号码识别 --&gt;
        &lt;meta name="format-detection" content="telephone=no"&gt;
        &lt;!-- 禁止Windows Phone 8+的触碰时高亮 --&gt;
        &lt;meta name="msapplication-tap-highlight" content="no"&gt;
        &lt;!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes --&gt;
        &lt;!-- 
            视口元标签：指定应用程序占用屏幕的多大空间，以及应用程序如何缩放（zoom） 
            minimum-scale、maximum-scale 最小/最大缩放比率 initial-scale 为初始缩放比率
            user-scalable 是否允许用户缩放
            width、height 界面的宽高
        --&gt;
        &lt;meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"&gt;
        &lt;link rel="stylesheet" type="text/css" href="css/index.css"&gt;
        &lt;title&gt;Hello World&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div class="app"&gt;
            &lt;h1&gt;Apache Cordova&lt;/h1&gt;
            &lt;div id="deviceready" class="blink"&gt;
                &lt;p class="event listening"&gt;Connecting to Device&lt;/p&gt;
                &lt;p class="event received"&gt;Emulater is Ready&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;!-- 
            该JS是 Apache Cordova 提供的，用于访问设备硬件（例如摄像头、GPS）的JavaScript API
            该JS只是一个占位符，没有对应的文件。该脚本在运行时由PhoneGap Developer App注入；或者在构建时由Cordova CLI注入
        --&gt;
        &lt;script type="text/javascript" src="cordova.js"&gt;&lt;/script&gt;
        &lt;script type="text/javascript" src="js/index.js"&gt;&lt;/script&gt;
    &lt;/body&gt;
&lt;/html&gt;</pre><br />
<pre class="crayon-plain-tag">var app = {
    // 程序入口点
    initialize: function() {
        this.bindEvents();
    },
    // 绑定事件监听器，例如'load', 'deviceready', 'offline',  'online'
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    //事件deviceready是Cordova专有的，该事件发生后，Cordova提供的设备API加载完毕并可用
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
    },
    // 修改DOM内容
    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        console.log('Received Event: ' + id);
    }
};

app.initialize();</pre>
<div class="blog_h1">开发与调试指南</div>
<div class="blog_h2"><span class="graybg">开发最佳实践</span></div>
<div class="blog_h3"><span class="graybg">单页面应用（SPA）</span></div>
<p>Cordova应该是基于单页面应用设计的。所谓单页面应用，是指不存在URL导航的Web应用。单页面引用仅在最初加载一次页面，后续的更新通过JavaScript、Ajax完成。</p>
<p>单页面应用有利于增强移动应用的性能，因为避免了<span style="background-color: #c0c0c0;">重复加载</span>各种资产文件（脚本、图片）。单页面应用对Cordova有额外的好处，因为Cordova应用必须<span style="background-color: #c0c0c0;">等待deviceready事件</span>，URL导航导致重复的事件等待。</p>
<div class="blog_h3"><span class="graybg">性能方面的考虑</span></div>
<p>Cordova开发者往往错误的假设，移动设备能够达到和桌面应用一样性能。实际上，尽管移动设备已经长足发展了近十年，在电池、性能方面，仍然无法和桌面应用比较。注意以下几个方面：</p>
<ol>
<li>click vs touch：click事件被大量误用。大部分移动设备添加300ms的延迟，用以区分touch和touch hold。使用touchstart、touchend可能有很大的性能改善——避免频繁的UI更新和其它行为</li>
<li>CSS 变换 vs DOM操控：硬件加速的CSS变换比起基于JavaScript的动画，性能有极大的优势</li>
<li>网络延迟：尽量使用Cordova支持的本地存储机制，避免反复通过网络获取数据、资源</li>
</ol>
<div class="blog_h3"><span class="graybg">识别并处理离线状态</span></div>
<p>使用Cordova提供的offline、online事件的支持，你可以识别出离线状态，并正确的响应用户。注意，这两种事件并不是非常可靠，有时候你应当使用Ajax来判断设备是否真正的断开网络了。</p>
<p>注意：苹果的商店拒绝不能正确处理离线状态的APP上架。</p>
<div class="blog_h3"><span class="graybg">数据存储方案</span></div>
<p>有几种存储方案可以供Apache Cordova应用使用：</p>
<ol>
<li>LocalStorage：同步的基于键值对的存储</li>
<li><a href="http://dev.w3.org/html5/webdatabase/">WebSQL</a>：基于SQL语句的API，支持Android、iOS</li>
<li>IndexedDB：支持Windows 8、Windows Phone 8</li>
<li>cordova-plugin-file插件：缓存数据到本地文件系统</li>
</ol>
<div class="blog_h2"><span class="graybg">测试Cordova应用</span></div>
<p>测试Cordova应用时，你可以使用真实设备、模拟器，甚至是桌面浏览器。但是，在多种真实设备上测试是很有必要的： </p>
<ol>
<li>模拟器（Simulator）不能模拟一些真实存在的情况：例如低电池时，应用会出现某个问题，这个问题在模拟器上难以体现</li>
<li>模拟器（Emulator）和真实设备的行为存在不一致：某些模拟器会导致页面显示混乱，但是在真实设备上没有这种问题。4.1.2的AVD，运行5.4版本Cordova的HelloWorld应用，就存在页面显示混乱的情况。你可能需要禁用Host GPU加速</li>
<li>Simulator往往比真实设备快很多，而Emulator则慢很多</li>
<li>在不同OS的设备上测试是有必要的，应用的行为可能不符合预期</li>
</ol>
<div class="blog_h3"><span class="graybg">PhoneGap Developer App</span></div>
<p>使用PGDA可以避免编译、打包、部署到设备的繁冗步骤，在开发阶段能够节约很多时间。</p>
<div class="blog_h2"><span class="graybg">调试Cordova应用</span></div>
<div class="blog_h3"><span class="graybg">iOS Debugging</span></div>
<p>使用XCode可以调试Cordova应用Native的那一部分。</p>
<div class="blog_h3"><span class="graybg">Safari Remote Debugging with Web Inspector</span></div>
<p>使用Safari的web inspector，你可以Debug Webview和Cordova应用的JavaScript代码，仅支持OS X和iOS6+。通过OS X中的Safari连接到设备（或模拟器），可以使用Safari的dev tools调试Cordova应用。</p>
<div class="blog_h3"><span class="graybg">Chrome Remote Debugging</span></div>
<p>与Safari类似，Chrome Dev Tools也可以用来<a href="https://developers.google.com/chrome/mobile/docs/debugging">调试Cordova应用</a>。需要<span style="background-color: #c0c0c0;">Android 4.4、API 19+、Chrome 30+</span>才可以进行调试。使用<a href="https://github.com/google/ios-webkit-debug-proxy/">WebKit proxy</a>，Chrome Dev Tools也可以调试iOS应用。</p>
<div class="blog_h3"><span class="graybg">Ripple</span></div>
<p><a href="http://ripple.incubator.apache.org/">Ripple</a>是一个基于Web的移动设备环境模拟器，用于快速开发基于Apache Cordova、Blackberry WebWorks等框架的移动Web应用。</p>
<div class="blog_h3"><span class="graybg">GapDebug</span></div>
<p>综合性的移动应用调试工具，支持在现代移动设备（iOS、Android）上调试混合应用，对PhoneGap、Cordova提供非常好的支持。</p>
<p>该工具实质上是对Chrome Dev Tools的包装和增强。</p>
<p>具体参见：<a href="/gapdebug">使用GapDebug调试Phonegap应用</a></p>
<div class="blog_h1"><span class="graybg">Cordova生命周期事件</span></div>
<p>除非特别说明所有事件均在<pre class="crayon-plain-tag">document</pre> 对象上发布。</p>
<table class=" fixed-word-wrap full-width">
<thead>
<tr>
<td style="width: 20%; text-align: center;">事件</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>deviceready</td>
<td>对任何Cordova应用程序都非常关键，该事件的发生意味着Cordova设备API已经加载完毕、并可以使用。用法示例：<br />
<pre class="crayon-plain-tag">document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    // 现在可以安全的使用Cordova设备API了
}</pre>
</td>
</tr>
<tr>
<td>pause</td>
<td>当应用程序进入后台时，发布该事件<br />注意：在iOS中，此事件的监听器对Cordova API的调用、对alert、console.log的调用都被阻塞，直到resume发生时才执行。</td>
</tr>
<tr>
<td>resume</td>
<td>当应用程序从后台返回前台执行时，发布此事件<br />注意：在iOS中，resume的监听器中，对交互式函数（例如alert）的调用，必须异步执行，否则应用程序会挂起。下面是正确的代码示例：<br />
<pre class="crayon-plain-tag">document.addEventListener("resume", onResume, false);
function onResume() {
   setTimeout(function() {
       alert(1);
   }, 0);
}</pre>
</td>
</tr>
<tr>
<td>backbutton</td>
<td>当用户按下后退按钮时，发布此事件，可以覆盖后台按钮的默认行为<br />不支持iOS系统</td>
</tr>
<tr>
<td>menubutton</td>
<td>当用户按下菜单按钮时，发布此事件，可以覆盖菜单按钮的默认行为<br />不支持iOS系统</td>
</tr>
<tr>
<td>searchbutton</td>
<td>当用户按下搜索按钮时，发布此事件，可以覆盖搜索按钮的默认行为<br />仅支持Android系统 </td>
</tr>
<tr>
<td>volumedownbutton</td>
<td>当用户按下减小音量按钮时，发布此事件，仅支持Android、BlackBerry 10</td>
</tr>
<tr>
<td>volumeupbutton</td>
<td>当用户按下增大音量按钮时，发布此事件，仅支持Android、BlackBerry 10</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2"><strong>插件cordova-plugin-battery-status引入的事件</strong></td>
</tr>
<tr>
<td>batterycritical</td>
<td rowspan="3">
<p>这些事件都在window对象上发布。分别在关键电量、低电量、电池状态变化时（增减超过1%、或者插上电源、拔下电源）时发布。可以访问事件对象的如下属性：</p>
<ol>
<li>level，电量百分比数值，0-100</li>
<li>isPlugged，布尔型，判断是否插入电源</li>
</ol>
</td>
</tr>
<tr>
<td>batterylow</td>
</tr>
<tr>
<td>batterystatus</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2"><strong>插件cordova-plugin-network-information引入的事件</strong></td>
</tr>
<tr>
<td>online</td>
<td rowspan="2"> 当设备上线（连接到互联网）时，以及设备下线时，发布对应的事件</td>
</tr>
<tr>
<td>offline</td>
</tr>
</tbody>
</table>
<div class="blog_h1"><span class="graybg">Cordova插件API</span></div>
<p>Cordova自带了一个最小化的API集合，工程可以通过插件添加额外的API。本节介绍Cordova核心插件的API。</p>
<p>本节中，使用样式区分不同的API类型：</p>
<ol>
<li>斜体：表示静态（static）成员</li>
<li>下划线标注：类型定义（typedef）</li>
<li>括号后缀：表示方法/函数</li>
</ol>
<div class="blog_h3"><span class="graybg">cordova-plugin-battery-status</span></div>
<p>提供三个电池相关的事件，如上节所述</p>
<div class="blog_h3"><span class="graybg">cordova-plugin-camera </span></div>
<p>该插件定义了一个全局的<pre class="crayon-plain-tag">navigator.camera</pre> 对象，用于拍摄照片、从系统的图片库选择照片。该插件常用API如下表：</p>
<table class=" fixed-word-wrap full-width">
<thead>
<tr>
<td style="width: 15%; text-align: center;">所有者</td>
<td style="width: 20%; text-align: center;">方法/属性</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="5">navigator.<br />camera</td>
<td><em>getPicture()</em></td>
<td>
<pre class="crayon-plain-tag">camera.getPicture(
    onSuccess successCallback, 
    onError errorCallback, 
    CameraOptions options
)</pre></p>
<p>使用摄像头拍照，或者从设备的图片库中获取照片。如果<br /><pre class="crayon-plain-tag">options.sourceType == Camera.PictureSourceType.</pre> ：</p>
<ol>
<li><span style="color: #333333; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 22px;">CAMERA（默认）：打开摄像头并拍照，一旦拍照完毕，则关闭默认照相程序，并返回到当前应用</span></span></li>
<li>PHOTOLIBRARY、SAVEDPHOTOALBUM：显示一个对话框，让用户选择一个既有的照片。此时当前函数返回一个CameraPopoverHandle，用于重新定位图片选择对话框（例如设备的方向改变时）</li>
</ol>
<p>图片通过Base64编码或者URI的方式（默认）传递给<pre class="crayon-plain-tag">successCallback</pre> 。如果<br /><pre class="crayon-plain-tag">options.destinationType == Camera.DestinationType.</pre> ：</p>
<ol>
<li>FILE_URI（默认）：返回文件URI，对于Android返回<pre class="crayon-plain-tag">content://</pre> 形式的URI。这是最好的方式，因为现代设备的拍的照片、图片库中的照片的质量可能很高，而此插件没有对其进行缩小、压缩处理，因此使用DATA_URL可能导致内存方面的问题</li>
<li>NATIVE_URI：返回Native的URI</li>
<li>DATA_URL：返回Base64编码的字符串</li>
</ol>
<p>得到图片URI或者Base64编码后，你可以：</p>
<ol>
<li>使用<pre class="crayon-plain-tag">&lt;img&gt;</pre> 渲染到当前页面</li>
<li>存储到本地</li>
<li>发送到远程服务器</li>
</ol>
</td>
</tr>
<tr>
<td><em>cleanup()</em></td>
<td>清理图片临时文件，仅当options.sourceType为CAMERA、options.destinationType为FILE_URI时需要调用<br />仅支持iOS</td>
</tr>
<tr>
<td><span style="text-decoration: underline;"><em>onError()</em></span></td>
<td>获取照片的错误回调，入参：
<ol>
<li><span style="color: #333333; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 22px;">sring </span><span style="color: #333333; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 22px;">message：来自设备Native代码的错误信息</span></li>
</ol>
</td>
</tr>
<tr>
<td><em><span style="text-decoration: underline;">onSuccess()</span></em></td>
<td>获取照片的成功回调，入参：
<ol>
<li><span style="color: #333333; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 22px;">sring imageData：Base64图片数据或者URI</span></li>
</ol>
</td>
</tr>
<tr>
<td><em><span style="text-decoration: underline;">CameraOptions</span></em></td>
<td>
<p>用于指定摄像头参数的对象，包含以下属性：</p>
<ol>
<li>quality：图片质量，0-100，100表示全分辨率+无损压缩。注意摄像头的分辨率无法得知</li>
<li>destinationType、sourceType：参考getPicture()方法的介绍</li>
<li>allowEdit：在选择前，允许简单的编辑照片</li>
<li>encodingType：图像编码方式，默认Camera.EncodingType.JPEG</li>
<li>targetWidth、targetHeight：目标图片的尺寸，纵横比保持不变</li>
<li>mediaType：当sourceType为PHOTOLIBRARY 或SAVEDPHOTOALBUM时，指定媒体类型，默认Camera.MediaType.PICTURE</li>
<li>correctOrientation：修正照片的方向</li>
<li>saveToPhotoAlbum：在拍照后，保存照片到设备相册</li>
<li>popoverOptions：仅用于iOS的iPad，用来指定popover的位置</li>
<li>cameraDirection：使用前摄像头还是后摄像头，默认Camera.Direction.BACK</li>
</ol>
</td>
</tr>
<tr>
<td rowspan="5">Camera   </td>
<td>enum<br />DestinationType</td>
<td>图片目标类型，可选值：<br />DATA_URL<br />FILE_URI<br />NATIVE_URI</td>
</tr>
<tr>
<td>enum<br />EncodingType</td>
<td>图像编码方式，可选值：<br />JPEG<br />PNG </td>
</tr>
<tr>
<td>enum<br />MediaType</td>
<td>媒体类型，可选值： <br />PICTURE：仅选择图片<br />VIDEO：仅选择视频，对于视频，DestinationType只能时URI<br />ALLMEDIA：同时选择图片和视频</td>
</tr>
<tr>
<td>enum<br />PictureSourceType</td>
<td>图片来源类型，可选值：<br />PHOTOLIBRARY：图片库，对于Android和SAVEDPHOTOALBUM一样<br />CAMERA：即时拍照<br />SAVEDPHOTOALBUM：图片库，对于Android和SAVEDPHOTOALBUM一样</td>
</tr>
<tr>
<td>enum<br />Direction</td>
<td>使用哪个摄像头，可选值：BACK、FRONT</td>
</tr>
</tbody>
</table>
<div class="blog_h3"><span class="graybg">cordova-plugin-console</span></div>
<p>该插件确保<pre class="crayon-plain-tag">console.log()</pre> 能够正常工作，为非Android平台提供额外的函数支持。该插件定义了一个全局的<pre class="crayon-plain-tag">console</pre> 对象，并引入以下方法：</p>
<table class=" fixed-word-wrap full-width">
<thead>
<tr>
<td style="width: 25%; text-align: center;">方法</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>log</td>
<td style="vertical-align: top;" rowspan="12">这些方法支持C语言printf风格的字符串格式化：
<ol>
<li><span style="color: #333333; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 22px;">%j 格式化为JSON</span></span></li>
<li>%o 格式化为JSON</li>
<li>%c 格式化为''</li>
<li>%% 转义%</li>
<li>%* 其他均使用目标参数的<pre class="crayon-plain-tag">toString()</pre> 方法进行打印</li>
</ol>
</td>
</tr>
<tr>
<td>error</td>
</tr>
<tr>
<td>exception</td>
</tr>
<tr>
<td>warn</td>
</tr>
<tr>
<td>info</td>
</tr>
<tr>
<td>debug</td>
</tr>
<tr>
<td>assert</td>
</tr>
<tr>
<td>dir</td>
</tr>
<tr>
<td>dirxml</td>
</tr>
<tr>
<td>time</td>
</tr>
<tr>
<td>timeEnd</td>
</tr>
<tr>
<td>table</td>
</tr>
</tbody>
</table>
<div class="blog_h1">Cordova配置文件：config.xml</div>
<p>位于Cordova工程根目录的配置文件config.xml，可以在全局上控制Cordova应用程序的行为：</p>
<ol>
<li>指定核心Cordova API特性</li>
<li>启用Cordova插件</li>
<li>进行平台相关的设置</li>
</ol>
<p>config.xml指定的配置会影响所有应用程序和CordovaWebView实例。</p>
<p>当使用Cordova的命令行接口（CLI）构建工程时，该文件会被修改并拷贝到各平台的对应目录，例如<pre class="crayon-plain-tag">platforms/ios/AppName/config.xml</pre> </p>
<div class="blog_h2"><span class="graybg">全局与跨平台配置选项</span></div>
<pre class="crayon-plain-tag">&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!-- widget元素： id 当前应用程序的唯一标识，通常是域名倒写，在Android中对应了包名 version 主版本.次版本.补丁版本 --&gt;
&lt;widget id="cc.gmem.study.cordova" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"&gt;
    &lt;!-- 应用程序的正式名称，该名称会出现在设备的主屏幕，以及应用商店 --&gt;
    &lt;name&gt;CordovaStudy&lt;/name&gt;
    &lt;!-- 应用程序描述和作者信息，会显示在应用商店 --&gt;
    &lt;description&gt;
        A sample Apache Cordova application that responds to the deviceready event.
    &lt;/description&gt;
    &lt;author email="dev@cordova.apache.org" href="http://cordova.io"&gt;
        Apache Cordova Team
    &lt;/author&gt;
    &lt;!-- 指定应用的起始网页 --&gt;
    &lt;content src="index.html" /&gt;
    &lt;!-- 指定应用使用的Cordova插件 --&gt;
    &lt;plugin name="cordova-plugin-whitelist" spec="1" /&gt;
    &lt;!-- 指定应用可以和哪些外部域名进行交互，默认值允许与任何外部服务交互 --&gt;
    &lt;access origin="*" /&gt;
    &lt;!-- Intent白名单 --&gt;
    &lt;allow-intent href="http://*/*" /&gt;
    &lt;allow-intent href="https://*/*" /&gt;
    &lt;allow-intent href="tel:*" /&gt;
    &lt;allow-intent href="sms:*" /&gt;
    &lt;allow-intent href="mailto:*" /&gt;
    &lt;allow-intent href="geo:*" /&gt;
    &lt;!-- platform元素只会拷贝到对应平台下的config.xml中 --&gt;
    &lt;platform name="android"&gt;
        &lt;allow-intent href="market:*" /&gt;
        &lt;!-- 平台特定的方向设置 --&gt;
        &lt;preference name="Orientation" value="sensorLandscape" /&gt;
    &lt;/platform&gt;
    &lt;platform name="ios"&gt;
        &lt;allow-intent href="itms:*" /&gt;
        &lt;allow-intent href="itms-apps:*" /&gt;
        &lt;!-- IOS：同时设置portrait、landscape模式 --&gt;
        &lt;preference name="Orientation" value="all" /&gt;
    &lt;/platform&gt;
    &lt;!-- 以键值对的形式定义若干选项，键大小写不敏感 --&gt;
    &lt;preference&gt;
        &lt;!-- 是否隐藏设备顶部的状态栏 --&gt;
        &lt;preference name="Fullscreen" value="false" /&gt;
        &lt;!-- 支持Android、IOS。是否禁止拖拽滚动超过顶部或者底部，如果不需要“下拉以刷新”之类的功能，可以禁止 --&gt;
        &lt;preference name="DisallowOverscroll" value="false" /&gt;
        &lt;!-- 支持Android、Blackberry。应用的背景色 --&gt;
        &lt;preference name="BackgroundColor" value="0xff0000ff" /&gt;
        &lt;!-- 支持Blackberry。隐藏键盘上方额外的工具栏 --&gt;
        &lt;preference name="HideKeyboardFormAccessoryBar" value="false" /&gt;
        &lt;!-- 锁定方向，禁止响应设备的转动。可选值landscape、portrait、default --&gt;
        &lt;preference name="Orientation" value="default" /&gt;
    &lt;/preference&gt;
    &lt;!-- 
        如果使用CLI，添加的插件不会反应到feature元素，但是如果使用针对特定平台的config.xml，
        可以设置feature元素，以启用设备级别的API或者外部插件
    --&gt;
    &lt;!-- 在Android平台上启用Device API --&gt;
    &lt;feature name="Device"&gt;
        &lt;param name="android-package" value="org.apache.cordova.device.Device" /&gt;
    &lt;/feature&gt;
    &lt;!-- 在IOS平台上启用Device API --&gt;
    &lt;feature name="Device"&gt;
        &lt;param name="ios-package" value="CDVDevice" /&gt;
    &lt;/feature&gt;
    &lt;!-- 添加钩子，以扩展Cordova的功能 --&gt;
    &lt;hook type="after_plugin_install" src="scripts/afterPluginInstall.js" /&gt;
    
    &lt;!-- 指定应用程序图标，platform/width/height/density都是可选的，density为Android专有 --&gt;
    &lt;icon src="res/ios/icon.png" platform="ios" width="57" height="57" density="mdpi" /&gt;
    &lt;!-- 可以采用平台专有的方式指定图标 --&gt;
    &lt;platform name="android"&gt;
        &lt;icon src="res/android/ldpi.png" density="ldpi" /&gt;
        &lt;icon src="res/android/mdpi.png" density="mdpi" /&gt;
        &lt;icon src="res/android/hdpi.png" density="hdpi" /&gt;
        &lt;icon src="res/android/xhdpi.png" density="xhdpi" /&gt;
     &lt;/platform&gt;
     &lt;platform name="ios"&gt;
        &lt;!-- iOS 8.0+ --&gt;
        &lt;!-- iPhone 6 Plus  --&gt;
        &lt;icon src="res/ios/icon-60@3x.png" width="180" height="180" /&gt;
        &lt;!-- iOS 7.0+ --&gt;
        &lt;!-- iPhone / iPod Touch  --&gt;
        &lt;icon src="res/ios/icon-60.png" width="60" height="60" /&gt;
        &lt;icon src="res/ios/icon-60@2x.png" width="120" height="120" /&gt;
        &lt;!-- iPad --&gt;
        &lt;icon src="res/ios/icon-76.png" width="76" height="76" /&gt;
        &lt;icon src="res/ios/icon-76@2x.png" width="152" height="152" /&gt;
        &lt;!-- iOS 6.1 --&gt;
        &lt;!-- Spotlight Icon --&gt;
        &lt;icon src="res/ios/icon-40.png" width="40" height="40" /&gt;
        &lt;icon src="res/ios/icon-40@2x.png" width="80" height="80" /&gt;
        &lt;!-- iPhone / iPod Touch --&gt;
        &lt;icon src="res/ios/icon.png" width="57" height="57" /&gt;
        &lt;icon src="res/ios/icon@2x.png" width="114" height="114" /&gt;
        &lt;!-- iPad --&gt;
        &lt;icon src="res/ios/icon-72.png" width="72" height="72" /&gt;
        &lt;icon src="res/ios/icon-72@2x.png" width="144" height="144" /&gt;
        &lt;!-- iPhone Spotlight and Settings Icon --&gt;
        &lt;icon src="res/ios/icon-small.png" width="29" height="29" /&gt;
        &lt;icon src="res/ios/icon-small@2x.png" width="58" height="58" /&gt;
        &lt;!-- iPad Spotlight and Settings Icon --&gt;
        &lt;icon src="res/ios/icon-50.png" width="50" height="50" /&gt;
        &lt;icon src="res/ios/icon-50@2x.png" width="100" height="100" /&gt;
     &lt;/platform&gt;
     
     &lt;!-- 指定启动画面，也可用使用Splashscreen插件，动态编程控制 --&gt;
     &lt;platform name="android"&gt;
        &lt;!-- you can use any density that exists in the Android project --&gt;
        &lt;splash src="res/screen/android/splash-land-hdpi.png" density="land-hdpi"/&gt;
        &lt;splash src="res/screen/android/splash-land-ldpi.png" density="land-ldpi"/&gt;
        &lt;splash src="res/screen/android/splash-land-mdpi.png" density="land-mdpi"/&gt;
        &lt;splash src="res/screen/android/splash-land-xhdpi.png" density="land-xhdpi"/&gt;

        &lt;splash src="res/screen/android/splash-port-hdpi.png" density="port-hdpi"/&gt;
        &lt;splash src="res/screen/android/splash-port-ldpi.png" density="port-ldpi"/&gt;
        &lt;splash src="res/screen/android/splash-port-mdpi.png" density="port-mdpi"/&gt;
        &lt;splash src="res/screen/android/splash-port-xhdpi.png" density="port-xhdpi"/&gt;
    &lt;/platform&gt;

    &lt;platform name="ios"&gt;
        &lt;!-- images are determined by width and height. The following are supported --&gt;
        &lt;splash src="res/screen/ios/Default~iphone.png" width="320" height="480"/&gt;
        &lt;splash src="res/screen/ios/Default@2x~iphone.png" width="640" height="960"/&gt;
        &lt;splash src="res/screen/ios/Default-Portrait~ipad.png" width="768" height="1024"/&gt;
        &lt;splash src="res/screen/ios/Default-Portrait@2x~ipad.png" width="1536" height="2048"/&gt;
        &lt;splash src="res/screen/ios/Default-Landscape~ipad.png" width="1024" height="768"/&gt;
        &lt;splash src="res/screen/ios/Default-Landscape@2x~ipad.png" width="2048" height="1536"/&gt;
        &lt;splash src="res/screen/ios/Default-568h@2x~iphone.png" width="640" height="1136"/&gt;
        &lt;splash src="res/screen/ios/Default-667h.png" width="750" height="1334"/&gt;
        &lt;splash src="res/screen/ios/Default-736h.png" width="1242" height="2208"/&gt;
        &lt;splash src="res/screen/ios/Default-Landscape-736h.png" width="2208" height="1242"/&gt;
    &lt;/platform&gt;
&lt;/widget&gt;</pre>
<div class="blog_h2"><span class="graybg">安卓配置选项</span></div>
<pre class="crayon-plain-tag">&lt;!-- 
    应用程序是否保持后台运行，甚至在pause事件发生之后 
    设置为fasle不会在pause事件后终止应用，而是仅仅当应用位于后台时，暂停CordovaWebView中代码的执行
--&gt;
&lt;preference name="KeepRunning" value="true"/&gt;
&lt;!-- 加载页面超时的毫秒数 --&gt;
&lt;preference name="LoadUrlTimeoutValue" value="20000"/&gt;
&lt;!-- 启动屏幕，位于res/drawable-*中的资源名称，不带扩展名 --&gt;
&lt;preference name="SplashScreen" value="splash"/&gt;
&lt;!-- 启动屏幕图片显示的毫秒数 --&gt;
&lt;preference name="SplashScreenDelay" value="3000"/&gt;
&lt;!-- 控制通过InAppBrowser打开的页面，是否可以和通过默认浏览器打开的页面访问同一localStorage和WebSQL --&gt;
&lt;preference name="InAppBrowserStorageEnabled" value="true"/&gt;
&lt;!-- 默认为null，如果设置，那么在加载第一个页面时，显示指定的标题、消息以及一个spinner。标题和消息使用逗号分隔 --&gt;
&lt;preference name="LoadingDialog" value="My Title,My Message"/&gt;
&lt;!-- 默认为null，与上一个配置类似，但是用于除了第一个页面的所有其它页面 --&gt;
&lt;preference name="LoadingPageDialog" value="My Title,My Message"/&gt;
&lt;!-- 默认为null，出错时显示的页面 --&gt;
&lt;preference name="ErrorUrl" value="myErrorPage.html"/&gt;
&lt;!-- 是否在屏幕顶部显示标题 --&gt;
&lt;preference name="ShowTitle" value="false"/&gt;
&lt;!-- 设置应用的日志级别：ERROR, WARN, INFO, DEBUG, VERBOSE --&gt;
&lt;preference name="LogLevel" value="ERROR"/&gt;
&lt;!-- 设置Activity的android:launchMode属性 --&gt;
&lt;preference name="AndroidLaunchMode" value="singleTop"/&gt;
&lt;!-- 设置User Agent，默认不设置 --&gt;
&lt;preference name="OverrideUserAgent" value="Mozilla/5.0 My Browser" /&gt;</pre>
<div class="blog_h1">指定平台或插件的版本</div>
<p>从Cordova4.3开始，支持保存（save ）、恢复（restore ）平台支持版本、插件版本信息。</p>
<p>当使用<pre class="crayon-plain-tag">--save</pre> 选项调用<pre class="crayon-plain-tag">cordova platform</pre> 、<pre class="crayon-plain-tag">cordova plugin</pre> 命令时，会自动把版本信息存放到config.xml中。执行<pre class="crayon-plain-tag">cordova prepare</pre> 时，会从config.xml中读取版本信息，并同步相应文件到platforms子目录中。</p>
<div class="blog_h3"><span class="graybg">保存平台版本</span></div>
<p>执行下面的命令，即可保存特定版本的平台：</p>
<pre class="crayon-plain-tag"># 命令格式
cordova platform add &lt;platform[@&lt;version&gt;] | directory | git_url&gt; --save
# 命令举例
cordova platform add android --save
cordova platform add android@3.7.0 --save    #后续不带@version添加平台，自动使用 3.7.0版本
cordova platform add android@https://github.com/apache/cordova-android.git​ --save
cordova platform add C:/path/to/android/platform --save

# 保存所有平台的版本
cordova platform save</pre>
<p>运行此命令后，config.xml中出现类似下面的条目：</p>
<pre class="crayon-plain-tag">&lt;engine name="android" spec="~4.0.0" /&gt;</pre>
<p>执行下面的命令，可以更新特定平台的版本： </p>
<pre class="crayon-plain-tag"># 命令格式
cordova platform update &lt;platform[@&lt;version&gt;] | directory | git_url&gt; --save

# 命令举例
cordova platform update android --save
cordova platform update android@3.8.0 --save
cordova platform update /path/to/android/platform --save</pre>
<div class="blog_h3"><span class="graybg">保存插件版本</span></div>
<p>执行下面的命令，即可保存插件版本到config.xml：</p>
<pre class="crayon-plain-tag"># 命令格式
cordova plugin add &lt;plugin[@&lt;version&gt;] | directory | git_url&gt; --save

# 命令举例
cordova plugin add cordova-plugin-console --save
cordova plugin add cordova-plugin-console@0.2.13 --save     #后续不带@version添加此插件，自动使用0.2.13版本
cordova plugin add https://github.com/apache/cordova-plugin-console.git --save
cordova plugin add C:/path/to/console/plugin --save

# 保存所有插件的版本
cordova plugin save</pre>
<p>运行此命令后，config.xml中出现类似下面的条目：</p>
<pre class="crayon-plain-tag">&lt;plugin name="cordova-plugin-console" spec="~1.0.0" /&gt;</pre>
<p>执行下面的命令，可以更新特定插件的版本： </p>
<pre class="crayon-plain-tag"># 命令格式
cordova plugin update &lt;plugin[@&lt;version&gt;] | directory | git_url&gt; --save

# 命令举例
cordova plugin update cordova-plugin-console --save
cordova plugin update cordova-plugin-console@0.2.13 --save
cordova plugin update /path/to/console/plugin --save</pre>
<div class="blog_h1"><span class="graybg"> 隐私与安全</span></div>
<div class="blog_h2"><span class="graybg">隐私指南</span></div>
<p>移动应用的隐私问题是每个移动App都需要关注的内容，用户需要它们的私人信息被合理使用，并不泄漏。下面是一些被广泛接受的建议：</p>
<ol>
<li>隐私策略（Privacy Policy）：使用平白的语言声明你的App的隐私策略</li>
<li>敏感信息的收集：在获取敏感信息，例如通讯录、地理位置、摄像机信息前，获得用户的许可</li>
<li>与第三方共享敏感信息：如果你的App获取的信息需要与第三方网站/应用共享，应当获得用户许可</li>
<li>仅在必要的时候才收集隐私信息</li>
</ol>
<div class="blog_h2"><span class="graybg">安全指南</span></div>
<p>本节包含一些开发Cordova应用时，处理安全问题的最佳实践。</p>
<ol>
<li>不要使用自签名的网站证书：如果你的服务器使用SSL，务必使用知名CA签发的数字证书</li>
<li>避免使用IFrame引用外部网页（不受你控制的第三方网站）：位于白名单中的网页，如果运行在IFrame中，它是可以访问Native Cordova Bridge的。引用外部链接，最好使用<span style="background-color: #c0c0c0;">InAppBrowser</span>，外部链接不会有机会执行Cordova API</li>
<li>关于域名白名单：<span style="background-color: #c0c0c0;">Android API 10以下</span>、<span style="background-color: #c0c0c0;">WP8中的IFrame和XMLHttpRequest</span>，都不受域名白名单控制，这意味着任何网页都可以调用Cordova接口</li>
<li>不要缓存敏感信息，例如用户名、密码</li>
<li>避免使用<pre class="crayon-plain-tag">eval()</pre> ，除非你确切知道脚本的内容</li>
</ol>
<div class="blog_h3"><span class="graybg">域名白名单配置</span></div>
<p>域名白名单（Domain whitelisting）机制用来控制Cordova应用对外部域名的访问。默认的，新创建的App<span style="background-color: #c0c0c0;">被允许访问所有外部域名</span>，在产品发布时，你必须确定需要访问哪些域名，并进行白名单配置。</p>
<p>对于Android和iOS，上述安全策略通过插件cordova-plugin-whitelist实现，具有更好的安全性和可配置性，推荐使用：</p>
<pre class="crayon-plain-tag">&lt;!-- 
    导航白名单（Navigation Whitelist）
    控制WebView可以被导航到那些URL，仅应用到顶级导航 
--&gt;
&lt;!-- 允许连接到google.com--&gt;
&lt;allow-navigation href="http://google.com/*" /&gt;
&lt;!-- 允许使用HTTP/HTTPS或者其它任何协议连接到google.com的所有子域 --&gt;
&lt;allow-navigation href="*://*.google.com/*" /&gt;
&lt;!-- 允许导航到任意网站--&gt;
&lt;allow-navigation href="*" /&gt;
&lt;!-- 上面一条等价于这三条：--&gt;
&lt;allow-navigation href="http://*/*" /&gt;
&lt;allow-navigation href="https://*/*" /&gt;
&lt;allow-navigation href="data:*" /&gt;


&lt;!-- 
    Intent白名单（Intent Whitelist）
    控制App可以要求系统打开哪些URL，默认任何URL都不允许 
--&gt;
&lt;!-- 允许在一个浏览器窗口中打开网页 --&gt;
&lt;allow-intent href="http://*/*" /&gt;
&lt;allow-intent href="https://*/*" /&gt;
&lt;allow-intent href="http://google.com/*" /&gt;
&lt;allow-intent href="*://*.example.com/*" /&gt;
&lt;!-- 允许在短信应用中打开SMS链接 --&gt;
&lt;allow-intent href="sms:*" /&gt;
&lt;!-- 允许拨打电话 --&gt;
&lt;allow-intent href="tel:*" /&gt;
&lt;!-- 允许打开地图 --&gt;
&lt;allow-intent href="geo:*" /&gt;
&lt;!-- 允许使用对应的App打开所有其它类型的URL --&gt;
&lt;allow-intent href="*" /&gt;


&lt;!-- 
    网络请求白名单（Network Request Whitelist）
    控制哪些网络请求被允许：Ajax、images等
    注意，最好使用Content Security Policy（CSP），CSP更安全。这节的配置主要用于不支持CSP的老旧Webview
    默认Android允许访问https://ssl.gstatic.com/accessibility/javascript/android/，这确保TalkBack正常工作
--&gt;
&lt;!-- 允许对google.com执行Ajax、图片请求 --&gt;
&lt;access origin="http://*.google.com" /&gt;
&lt;!-- 允许针对content URL的请求 --&gt;
&lt;access origin="content:///*" /&gt;
&lt;!-- 允许任何请求 --&gt;
&lt;access origin="*" /&gt;</pre>
<p>对于其它平台，Cordova应用依赖于config.xml中的<pre class="crayon-plain-tag">&lt;access&gt;</pre> 元素进行白名单设置：</p>
<pre class="crayon-plain-tag">&lt;!-- 允许访问google.com --&gt;
&lt;access origin="http://google.com" /&gt;
&lt;!-- 允许访问HTTPS版本的google.com --&gt;
&lt;access origin="https://google.com" /&gt;
&lt;!-- 允许访问maps.google.com --&gt;
&lt;access origin="http://maps.google.com" /&gt;
&lt;!-- 允许访问google.com的所有子域名 --&gt;
&lt;access origin="http://*.google.com" /&gt;
&lt;!-- 允许访问所有网站 --&gt;
&lt;access origin="*" /&gt;</pre>
<div class="blog_h3"><span class="graybg">内容安全策略（Content Security Policy）</span></div>
<p>参见：<a href="/html-faq#csp">HTML知识集锦</a></p>
<p>CSP用于控制图片、Ajax、<pre class="crayon-plain-tag">&lt;video&gt;</pre> 、WebSocket等所有请求。上面的whitelist插件的network request whitelist，<span style="background-color: #c0c0c0;">只能控制</span>图片、Ajax，因此有必要在HTML的<pre class="crayon-plain-tag">&lt;meta&gt;</pre> 配置CSP：</p>
<pre class="crayon-plain-tag">&lt;!-- 较为安全的默认值 --&gt;
&lt;meta http-equiv="Content-Security-Policy"
    content="default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *"&gt;

&lt;!-- 允许同源和google.com的所有内容--&gt;
&lt;meta http-equiv="Content-Security-Policy" content="default-src 'self' google.com"&gt;

&lt;!-- 
    允许所有内容，除了：
    对于CSS，仅允许同源的CSS文件，以及内联的样式
    对于脚本，仅允许同源的JS文件，内联的JavaScript脚本，以及eval()
--&gt;
&lt;meta http-equiv="Content-Security-Policy"
    content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"&gt;

&lt;!-- 仅允许同源的、通过HTTPS的Ajax请求 --&gt;
&lt;meta http-equiv="Content-Security-Policy" content="default-src 'self' https:"&gt;

&lt;!-- 允许来自google.com的IFrame --&gt;
&lt;meta http-equiv="Content-Security-Policy" content="default-src 'self'; frame-src 'self' https://google.com"&gt;</pre>
<div class="blog_h1"><span class="graybg">Cordova Hooks</span></div>
<p>钩子是Cordova Application、Plugin添加的特殊脚本，用于<span style="background-color: #c0c0c0;">定制化Cordova的命令</span>。可以在hooks目录添加钩子，也可以在config.xml、plugin.xml中声明钩子。钩子按照下面的<span style="background-color: #c0c0c0;">顺序串行执行</span>：</p>
<ol>
<li>来自/hooks目录的Application钩子</li>
<li>来自config.xml的Application钩子</li>
<li>来自plugins/.../plugin.xml的插件钩子</li>
</ol>
<p>目前支持的钩子类型有：</p>
<ol>
<li>after_build</li>
<li>after_compile</li>
<li>after_clean</li>
<li>after_docs</li>
<li>after_emulate</li>
<li>after_platform_add</li>
<li>after_platform_rm</li>
<li>after_platform_ls</li>
<li>after_plugin_add</li>
<li>after_plugin_ls</li>
<li>after_plugin_rm</li>
<li>after_plugin_search</li>
<li>after_plugin_install  仅执行被安装插件声明在plugin.xml中的钩子</li>
<li>after_prepare</li>
<li>after_run</li>
<li>after_serve</li>
<li>before_build</li>
<li>before_clean</li>
<li>before_compile</li>
<li>before_docs</li>
<li>before_emulate</li>
<li>before_platform_add</li>
<li>before_platform_rm</li>
<li>before_platform_ls</li>
<li>before_plugin_add</li>
<li>before_plugin_ls</li>
<li>before_plugin_rm</li>
<li>before_plugin_search</li>
<li>before_plugin_install  仅执行被安装插件声明在plugin.xml中的钩子</li>
<li>before_plugin_uninstall  仅执行被卸载插件声明在plugin.xml中的钩子</li>
<li>before_prepare</li>
<li>before_run</li>
<li>before_serve</li>
<li>pre_package 仅支持Windows、Windows Phone平台</li>
</ol>
<div class="blog_h3"><span class="graybg">在何处存放钩子</span></div>
<p>如果把钩子存放在hooks目录，必须遵从严格的命名规定：<pre class="crayon-plain-tag">hooks/钩子类型/脚本文件.js</pre> 。例如，如果你需要在prepare命令执行完毕后，附加一些行为，可以编写脚本：<pre class="crayon-plain-tag">hooks/after_prepare/cordova-syncdown.js</pre> 。应避免使用hooks目录，未来的Cordova版本可能废弃这种方式。</p>
<p>在config.xml、plugin.xml中声明钩子的方式如下：</p>
<pre class="crayon-plain-tag">&lt;hook type="before_build" src="scripts/appBeforeBuild.bat" /&gt;
&lt;hook type="before_build" src="scripts/appBeforeBuild.js" /&gt;
&lt;hook type="before_plugin_install" src="scripts/appBeforePluginInstall.js" /&gt;</pre>
<div class="blog_h3"><span class="graybg">钩子编程接口</span></div>
<p>一般使用NodeJS来编写钩子，Node模块定义的方式如下：</p>
<pre class="crayon-plain-tag">module.exports = function( ctx )
{
}</pre>
<p>其中ctx包含很多上下文信息： </p>
<pre class="crayon-plain-tag">{
  "hook": "after_prepare",
  "scriptLocation": "after_prepare/script.js",
  "cmdLine": "/path/to/cordova arguments",
  "opts": {
    "projectRoot":"/path/to/project",
    "cordova": {
      "platforms": ["android"],
      "plugins": ["com.plugin.withhooks"],
      "version": "0.21.7-dev"
    },
    "plugin": {
      "id": "com.plugin.withhooks",
      "pluginInfo": {
        ...
      },
      "platform": "android",
      "dir": "/path/to/project/plugins/com.plugin.withhooks"
    }
  },
  "cordova": {} //cordova object
}</pre>
<div class="blog_h1"><span class="graybg">常见问题</span></div>
<div class="blog_h2"><span class="graybg">避免Cordova在构建时自动下载gradle</span></div>
<p>修改$CORDOVA_PROJECT_ROOT/platforms/android/cordova/lib/build.js 中如下变量的值：</p>
<pre class="crayon-plain-tag">var distributionUrl = 'distributionUrl=../../../gradle-2.2.1-all.zip';</pre>
<p>然后，把本地磁盘的 gradle-2.2.1-all.zip拷贝或者链接到$CORDOVA_PROJECT_ROOT/platforms 即可。执行<pre class="crayon-plain-tag">cordova prepare</pre>  时，会从config.xml中读取版本信息，并同步到已经添加的各平台的对应目录中。</p>
<p>让Gradle使用本地Maven仓库中的构件，避免不必要的下载动作</p>
<p>修改$CORDOVA_PROJECT_ROOT/platforms/android/build.gradle中的内容：</p>
<pre class="crayon-plain-tag">repositories {
    mavenLocal()
    //添加上面一行的内容
    mavenCentral()
}</pre>
<p>&nbsp;</p>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/mobile-app-dev-with-apache-cordova">基于Apache Cordova开发移动应用程序</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/mobile-app-dev-with-apache-cordova/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
