使用Cordova建立第一个App和Cordova构建环境的配置

引言

经过上一篇文章咱们已经对 Hybrid App 有了必定的了解,而且根据实际业务状况选择了 Cordova 来开发咱们的APP, 若是对这些还不了解的话请查看上一篇文章,那么接下来咱们就开始Cordova 之旅把!javascript

安装Cordova CLI

因为Cordova命令行工具做为npm包发布,这对于咱们前端开发的同窗来讲实在是太方便了!html

#全局安装Cordova
$ npm install -g cordova

:对于在OS X和Linux上, npm命令前加sudo 是由于 cordova 须要安装在您的当前用户没有写入权限的目录或其余受限制目录好比 /usr/local/share。若是你使用像nvm/nave或者具备安装目录的写入权限,那么你能够省略sudo前缀。前端

建立App

建立一个APP只须要执行:java

$ cordova create hello com.example.hello HelloWorld

让咱们来一块儿剖析下 cordova create 到底作了些什么?根据官方描述该命令支持四个参数:

  1. path:也就是项目的目录名称
  2. ID:项目的ID,用于写入config.xml的widget中,一般格式为 com.example.hello
  3. name:应用程序的显示名称
  4. 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();
}

项目建立成功以后咱们将获得以下目录结构node

hello/
|-- config.xml      #项目配置文件
|-- hooks/          #存放Cordova 的钩子
|-- node_modules/
|-- res/            #存放一些各平台的icon或者首屏图等资源
|-- www/            #静态网页资源
|-- platforms/      #各平台存放目录
|-- plugins/        #插件目录
|-- package.json

添加 Android 平台及插件

初始化项目有了,接下来就是添加咱们须要支持的平台了,例如:Android 、 iOS 这里以 Android 为例mysql

# 切换到项目目录下
$ cd hello

# 添加Android平台
$ cordova platform add android --save

# 添加摄像头插件
$ cordova plugin add cordova-plugin-camera

cordova platform add、cordova plugin add 原理其实和cordova create 都差很少,cordova cli 的模板文件夹以下:感兴趣的童鞋能够深究下!linux

Cordova 编译打包 Android APP 生成APK安装包

通过上面对cordova cli 的分析来看,cordova cli 只是一个命令行工具,它不具有任何环境的能力,因此,要编译android 的APK文件首先咱们要安装android的环境android

在安装环境以前先说下我遇到的坑!引用官方的话:“自cordova-android@4.0.0起,Cordova为Android项目使用 Gradle构建。”坑的是Grable安装不上,即便安装上以后在cordova编译的时候也会报Grable安装错误!最终成功安装的结论为:“干掉cordova在编译时从google下载Gradle”。以 linux 系统为例安装Gradle步骤以下:sql

下载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就很少废话了!shell

对于一个前端开发者来讲,我只须要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

说明

若是将以上技术栈描述清楚须要不小的篇幅,因此我会将文章进行拆分:

1. Hybrid App 开发实践总结 ~开篇
2. 使用Cordova建立第一个App和Cordova构建环境的配置 (本文)
3. 使用 jenkins 自动化编译cordova生成 android APK
4. 服务器端code-push-server、mysql服务的架设
5. 客户端code-push插件的引入及code-push-cli的使用
7. 如何使用纯shell编写一个快速搭建开发者环境的命令行工具和安卓端真机调试