引言
通過上一篇文章我們已經對 Hybrid App 有了一定的了解,並且根據實際業務情況選擇了 Cordova 來開發我們的APP, 如果對這些還不了解的話請查看上一篇文章,那么接下來我們就開始Cordova 之旅把!
安裝Cordova CLI
由於Cordova命令行工具作為npm包發布,這對於我們前端開發的同學來說實在是太方便了!
#全局安裝Cordova
$ npm install -g cordova
注 :對於在OS X和Linux上, npm命令前加sudo 是因為 cordova 需要安裝在您的當前用戶沒有寫入權限的目錄或其他受限制目錄比如 /usr/local/share。如果你使用像nvm/nave或者具有安裝目錄的寫入權限,那么你可以省略sudo前綴。
創建App
創建一個APP只需要執行:
$ cordova create hello com.example.hello HelloWorld
讓我們來一起剖析下 cordova create 到底做了些什么?根據官方描述該命令支持四個參數:
- path:也就是項目的目錄名稱
- ID:項目的ID,用於寫入config.xml的widget中,通常格式為 com.example.hello
- name:應用程序的顯示名稱
- options:項目的可選配置項
- --template:可執行項目的模版文件
- --copy-from 指定src
- --link-to 可將一個前端資源目錄鏈接到項目的www目錄下而不是一個副本
通過部分 Cordova cli 源碼我們可以大致知道Cordova是如何幫我們創建一個初始化工程的
var paths = {};
//從 cordova-app-hello-world npm包中獲取config.xml文件
paths.configXml = path.join(require('cordova-app-hello-world').dirname, 'config.xml');
//從 cordova-app-hello-world npm包中獲取 www 目錄
paths.www = path.join(require('cordova-app-hello-world').dirname, 'www');
//從 cordova-app-hello-world npm包中獲取 hooks 目錄
paths.hooks = path.join(require('cordova-app-hello-world').dirname, 'hooks');
// 從 cordova-app-hello-world npm包中獲取 package.json 文件
var dirAlreadyExisted = fs.existsSync(dir);//dir為 cordova create 的第一個參數 ptah
//判斷當前path是否存在不存在直接創建
if (!dirAlreadyExisted) {
fs.mkdirSync(dir);
}
try {
//如果指定了 --template 則從模版復制項目到新項目下
if (cfg.lib.www.template) { copyTemplateFiles(import_from_path, dir, isSubDir); }
//如果指定了 --link 則創建鏈接到項目
if (cfg.lib.www.link) { linkFromTemplate(import_from_path, dir); }
//如果沒有沒有指定 --template 或者 --link 則直接用 cordova-app-hello-world npm包
copyIfNotExists(paths.www, path.join(dir, 'www'));
copyIfNotExists(paths.hooks, path.join(dir, 'hooks'));
var configXmlExists = projectConfig(dir); // moves config to root if in www
if (paths.configXml && !configXmlExists) {
shell.cp(paths.configXml, path.join(dir, 'config.xml'));
}
} catch (e) {
if (!dirAlreadyExisted) {
shell.rm('-rf', dir);
}
if (process.platform.slice(0, 3) === 'win' && e.code === 'EPERM') {
throw new CordovaError('Symlinks on Windows require Administrator privileges');
}
throw e;
}
//獲取 package.json 文件
var pkgjsonPath = path.join(dir, 'package.json');
// Update package.json name and version fields
if (fs.existsSync(pkgjsonPath)) {
delete require.cache[require.resolve(pkgjsonPath)];
var pkgjson = require(pkgjsonPath);
//指定項目名稱,也就是我們 cordova create 命令的第三個參數
if (cfg.name) {
pkgjson.displayName = cfg.name;
}
//指定項目ID,也就是我們 cordova create 命令的第二個參數
if (cfg.id) {
pkgjson.name = cfg.id.toLowerCase();
} else if (!cfg.id) {
//設置默認ID為 helloworld
pkgjson.name = 'helloworld';
}
pkgjson.version = '1.0.0';
fs.writeFileSync(pkgjsonPath, JSON.stringify(pkgjson, null, 4), 'utf8');
}
//創建 platforms(后期添加的Android和iOS平台都放在此文件夾) 和 plugins(插件)文件夾
if (!fs.existsSync(path.join(dir, 'platforms'))) { shell.mkdir(path.join(dir, 'platforms')); }
if (!fs.existsSync(path.join(dir, 'plugins'))) { shell.mkdir(path.join(dir, 'plugins')); }
var configPath = path.join(dir, 'config.xml');
// only update config.xml if not a symlink
if (!fs.lstatSync(configPath).isSymbolicLink()) {
// Write out id and name to config.xml; set version to 1.0.0 (to match package.json default version)
var conf = new ConfigParser(configPath);
if (cfg.id) conf.setPackageName(cfg.id);
if (cfg.name) conf.setName(cfg.name);
conf.setVersion('1.0.0');
conf.write();
}
項目創建成功之后我們將得到如下目錄結構
hello/
|-- config.xml #項目配置文件
|-- hooks/ #存放Cordova 的鈎子
|-- node_modules/
|-- res/ #存放一些各平台的icon或者首屏圖等資源
|-- www/ #靜態網頁資源
|-- platforms/ #各平台存放目錄
|-- plugins/ #插件目錄
|-- package.json
添加 Android 平台及插件
初始化項目有了,接下來就是添加我們需要支持的平台了,例如:Android 、 iOS 這里以 Android 為例
# 切換到項目目錄下
$ cd hello
# 添加Android平台
$ cordova platform add android --save
# 添加攝像頭插件
$ cordova plugin add cordova-plugin-camera
cordova platform add、cordova plugin add 原理其實和cordova create 都差不多,cordova cli 的模板文件夾如下:感興趣的童鞋可以深究下!

Cordova 編譯打包 Android APP 生成APK安裝包
經過上面對cordova cli 的分析來看,cordova cli 只是一個命令行工具,它不具備任何環境的能力,所以,要編譯android 的APK文件首先我們要安裝android的環境
在安裝環境之前先說下我遇到的坑!引用官方的話:“自cordova-android@4.0.0起,Cordova為Android項目使用 Gradle構建。”坑的是Grable安裝不上,即使安裝上之后在cordova編譯的時候也會報Grable安裝錯誤!最終成功安裝的結論為:“干掉cordova在編譯時從google下載Gradle”。以 linux 系統為例安裝Gradle步驟如下:
下載Gradle安裝包並安裝(別試圖從官網下載,除非你有梯子)
$ wget https://code.aliyun.com/shuoer/soft/raw/master/gradle-4.1-bin.zip
#解壓Gradle安裝包到你指定的目錄,我以${HOME}/.zs-tools/為例
$ unzip gradle-4.1-bin.zip -d ${HOME}/.zs-tools/
#添加Gradle的環境變量,讓系統能識別Gradle命令
echo 'export PATH=${HOME}/.zs-tools/gradle-4.1/bin:${PATH}' >> ${HOME}/.bashrc
#干掉cordova在編譯時從google下載Gradle編譯工具
#如果沒有這條命令,你休想cordova能編譯成功,除非你有梯子
echo 'export CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL=https://code.aliyun.com/shuoer/soft/raw/master/gradle-4.1-all.zip' >> ${HOME}/.bashrc
#使配置生效
$ source ${HOME}/.bashrc
Android環境的安裝
Android環境的安裝需要依賴java環境,而java環境的安裝其實百度上都可以查的到!沒什么復雜的步驟,而且開發人員基本都有了,java就不多廢話了!
對於一個前端開發者來說,我只需要android sdk 就可以了,不需要非安裝android studio,如果你從事android開發或者你想給cordova 開發一個android的插件的時候才可能用的到android studio!所以我選擇只安裝android SDK,以 linux 系統 shell 環境為 bash 為例步驟如下:
#下載android sdk for linux 包
$ wget https://code.aliyun.com/shuoer/soft/raw/master/android-sdk_r24.4.1-linux.tgz
#解壓 android-sdk 包到你指定的目錄,我以${HOME}/.zs-tools/為例
$ tar zxvf android-sdk_r24.4.1-linux.tgz -C ${HOME}/.zs-tools/
#添加 ANDROID_HOME 的環境變量
$ echo "export ANDROID_HOME=${HOME}/.zs-tools/android-sdk-linux" >> "${HOME}/.bashrc"
#添加 android tools 和 platform-tools 的環境變量
$ echo 'export PATH=${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools:${PATH}' >> "${HOME}/.bashrc"
#使配置文件生效
$ source ${HOME}/.bashrc
#創建 repositories.cfg 如果有該文件可跳過該步,主要解決 Android SDK Manager無法升級
$ touch ${HOME}/.android/repositories.cfg
#升級 android 所需要的tools和api(該命令耗時較長務必耐心等待)
# -a 表示升級所有 --no-ui 不要ui界面 --filter 只安裝我指定的部分
$ echo y | android update sdk -a --no-ui --filter tools,platform-tools,android-26,build-tools-26.0.2
問:為什么你總是喜歡用${HOME}/.zs-tools/文件夾存儲所有的環境文件
答:其實很簡單,就因為我“懶”!為什么說懶呢?如果您當前登錄的用戶是root,那您將環境安裝文件放到哪里都沒問題,但是對於非root用戶來說,放到任何非當前用戶的目錄下比如:/opt、/usr/share下時,當您在下載、解壓或者在執行 android 命令時需要在命令前加sudo!這是因為當前用戶沒有目標目錄的寫入權限!所以為避免不必要的權限麻煩,我選擇將文件放在用戶目錄下!
另外在linux 系統中以 . 點開頭的文件或文件夾都是隱藏的!只要自己管理好不會顯得很亂
編譯android的APK安裝包
雖然cordova 官網說明了cordova在編譯android的時候用的是grable,但是cordova cli 都幫我們處理,編譯一個debug版本的APK安裝包只需要執行如下:
#編譯一個可調試的安裝包(第一次編譯用時較長務必耐心等待)
$ cordova build android
編譯一個release版本的APK安裝包
$ cordova build android --release
說明
如果將以上技術棧描述清楚需要不小的篇幅,所以我會將文章進行拆分:
