发布时间:2014 年 2 月 28 日
Web 开发的一大优势在于,您可以使用丰富的工具来改进工作流程。
其中一个工具示例是 Grunt,这是一个 JavaScript 任务运行程序,可让您定义要在 Web 应用上执行的任务,从编译 Sass 和启动实时服务器到压缩图片、缩减 JavaScript 和运行 JSHint,然后再创建可用于生产环境的 build。
Yeoman 是一款有助于创建 Web 应用、生成样板代码、引入 Bower 和 npm 中的库以及创建包含预定义任务的 Grunt 文件的工具。
在本教程中,您将使用 Yeoman 创建一个新的基本 Web 应用,然后将 Android Studio 构建系统 (Gradle) 与 Grunt 集成,以构建 Web 应用。您还将设置 Grunt 任务以启动本地实时重新加载服务器,以便在浏览器中测试应用,这样您就不必每次更改 HTML、CSS 或 JavaScript 文件时都手动刷新页面。
前提条件
开始之前,您需要安装一些前提条件:
- 安装 Yeoman:https://github.com/yeoman/yeoman/wiki/Getting-Started
- 安装 Android Studio:https://developer.android.com/sdk/installing/studio.html
第 1 步:在 Android Studio 中使用 WebView 创建一个新项目
如需有关如何执行此操作的完整说明,请参阅入门指南。
第 2 步:为 Web 应用内容创建子目录
创建项目后,创建一个新的顶级目录。在 Android Studio 中,右键点击项目文件夹,然后依次选择 New > Directory。
将目录命名为 webapp
。
第 3 步:在新目录中创建一个 Yeoman 项目
在终端中,cd
到项目中的 webapp
目录。
cd <path-to-project>/webapp/
然后,使用 Yeoman 创建一个新的 Web 应用:
yo webapp
按照屏幕上的提示选择项目选项。您可能需要运行 sudo npm install
,具体取决于 npm 在您的机器上的安装方式。
在继续执行下一步之前,请通过运行以下命令测试应用:
grunt server
浏览器中应该会打开一个新的标签页,连接到由 Grunt 启动的本地服务器。如果您更改项目中的某个 HTML、CSS 或 JavaScript 文件,页面会自动重新加载并更新。
如果您运行 grunt build
,系统会创建一个新目录 dist
,并压缩、优化您的 Web 应用,并将其转换为此文件夹中可用于生产环境的版本。
第 4 步:配置 Gradle build
在 webapp
目录中,新建一个名为 build.gradle
的文件。
在新建的 build.gradle
文件中,添加以下内容:
import org.apache.tools.ant.taskdefs.condition.Os
task buildWebApp(type: Exec) {
executable = Os.isFamily(Os.FAMILY_WINDOWS) ? "grunt.cmd" : "grunt"
args = ["build"]
}
这会创建一个名为 buildWebApp
的新任务,其类型为预定义的 Exec
。然后,根据当前操作系统,将 Exec
中的 executable
变量设置为相关的 Grunt 命令。args
设置为 "build"
,这相当于在命令行上运行 grunt build
。最后,顶部的导入用于使用 Os.isFamily(Os.FAMILY_WINDOWS)
。
在使用以下新任务之前,我们需要让项目知道新的 build.gradle
文件。
在根目录中打开 settings.gradle
,然后添加以下代码行:
include ':webapp'
第 5 步:在构建 Android 应用时构建 Web 应用
构建 Web 应用,然后将该应用复制到 Android 应用的 assets
目录中。
将以下内容复制到 Android 应用的 build.gradle
文件中:
task copyWebApplication(type: Copy) {
from '../webapp/dist'
into 'src/main/assets/www'
}
task deleteWebApplication(type: Delete) {
delete 'src/main/assets/www'
}
copyWebApplication.dependsOn ':webapp:buildWebApp'
copyWebApplication.dependsOn deleteWebApplication
android.applicationVariants.all { variant ->
tasks.getByPath(":${project.name}:assemble${variant.buildType.name.capitalize()}").dependsOn copyWebApplication
}
我们来详细了解一下各个部分。
任务 copyWebApplication
task copyWebApplication(type: Copy) {
from '../webapp/dist'
into 'src/main/assets/www'
}
此 Copy
任务会从 webapp/dist
目录复制您的应用。我们要将文件复制到 src/main/assets/www
。如果任何必需的目录不存在,此任务还会创建必要的文件结构。
任务 deleteWebApplication
task deleteWebApplication(type: Delete) {
delete 'src/main/assets/www'
}
此删除任务会删除 assets/www
目录中的所有文件。
copyWebApplication.dependsOn
copyWebApplication.dependsOn ':webapp:buildWebApp'
copyWebApplication.dependsOn deleteWebApplication
第一行说明 copyWebApplication
依赖于 Web 应用的 build.gradle
文件中的 buildWebApp
任务。
第二行表示存在对 deleteWebApplication
任务的依赖项。
换句话说,在实际将任何文件复制到 assets
目录之前,请确保构建 Web 应用并删除 assets
目录的当前内容。
android.applicationVariants.all
android.applicationVariants.all { variant ->
tasks.getByPath(":${project.name}:assemble${variant.buildType.name.capitalize()}").dependsOn copyWebApplication
}
此任务会为项目的所有 build 和应用的每个版本指定依赖项。在这里,它会设置对 assemble
任务的依赖项以运行 copyWebApplication
。
assemble
任务会汇编项目的输出,因此需要先将 Web 应用复制到 Android 项目。
第 6 步:确保一切正常运行
在 Android Studio 中,您的 Android 应用 src
文件夹中不应包含 assets
目录。
将 WebView 设置为使用 index.html
页面:
mWebView.loadUrl("file:///android_asset/www/index.html");
点击 Run 以构建应用。您应该会在 www
子目录中看到包含 Web 应用的 assets
目录。
第 7 步:创建实时服务器并实时重新加载
实时重新加载功能非常适合快速更改 Web 应用。为此,您可以为应用创建两个“产品变种”:一个是实时服务器版本,另一个是静态版本,其中 Web 内容会打包到 Android 应用中。
在 Android 应用的 build.gradle
中,在 android
元素的末尾添加以下代码行:
android {
...
defaultConfig {
...
}
productFlavors {
staticbuild {
packageName "com.google.chrome.myapplication"
}
liveserver {
packageName "com.google.chrome.myapplication.liveserver"
}
}
}
现在,Gradle 支持您使用 liveserver 软件包名称创建应用版本,也可以使用常规软件包名称创建应用版本。如需检查是否成功,请点击 Sync Project with Gradle Files(位于顶部工具栏中的 Run 按钮旁边)。
然后,查看 Android Studio 左下角的 Build Variants,它会显示您可以构建哪些版本的应用。
对于每个 productFlavor
,都有调试和发布版本,Android Plugin for Gradle 会默认为您提供这些版本。这决定了 build 应为调试 build 还是适合部署到 Play 商店的发布 build。
现在,您有两个版本,但它们实际上还没有任何不同之处。
第 8 步:从实时服务器加载
现在,请根据您构建的产品变种,配置应用以加载不同的网址。
在 Android 应用中,所有商品变种通用的文件都位于 src/main
中。如需添加特定于一种产品变种的代码或资源,请在 src
下创建一个与 productFlavor
同名的其他目录。当您为该 build 变体进行构建时,Gradle 和 Android 插件会将这些额外的文件与 src/main
中的文件合并到一起。
将网址定义为字符串资源,并在代码中使用该资源,而不是硬编码网址。
创建文件夹
src/liveserver
和src/staticbuild
。在
liveserver
文件夹中,创建一个名为res
的新文件夹,并在其中创建一个名为values
的子文件夹。在其中创建一个名为config.xml
的文件。对staticbuild
文件夹重复此过程。在配置文件中,将以下代码行添加到
src/liveserver/res/values/config.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="init_url">https://<Your Local Machine IP Address>:9000</string> </resources>
将以下代码块添加到
src/staticbuild/res/values/config.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="init_url">file:///android_asset/www/index.html</string> </resources>
将 WebView 设置为使用这些配置文件中的
init_url
。mWebView.loadUrl(getString(R.string.init_url));
在
liveserver/AndroidManifest.xml
中创建一个名为AndroidManifest.xml
的新文件,并添加以下代码行:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="https://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET" /> </manifest>
这会为
liveserver
build 添加互联网权限。在
webapp/Gruntfile.js
中,查找以下内容:connect: { options: { port: 9000, livereload: 35729, // change this to '0.0.0.0' to access the server from outside hostname: **'localhost'** }, ... }
将
localhost
替换为0.0.0.0
,以便从本地网络访问您的本地服务器:connect: { options: { port: 9000, livereload: 35729, // change this to '0.0.0.0' to access the server from outside hostname: '**0.0.0.0'** }, ... }
如需测试更改,请执行以下操作:
启动实时服务器:
grunt server
在 Android Studio 中,在 Build Variant 选择中,选择 LiveserverDebug。然后点击运行。
您应该能够修改 HTML、CSS 和 JavaScript 内容,并立即在浏览器中看到修改后的效果。
现在,您有两个版本的应用:一个是从 Grunt 服务器实时重新加载的开发版本;另一个是本地打包到 Android 应用中的静态版本。