引言
通过上一篇文章我们已经对 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
说明
如果将以上技术栈描述清楚需要不小的篇幅,所以我会将文章进行拆分: