WebView 工作流程

发布时间:2014 年 2 月 28 日

Web 开发的一大优势在于,您可以使用丰富的工具来改进工作流程。

其中一个工具示例是 Grunt,这是一个 JavaScript 任务运行程序,可让您定义要在 Web 应用上执行的任务,从编译 Sass 和启动实时服务器到压缩图片、缩减 JavaScript 和运行 JSHint,然后再创建可用于生产环境的 build。

Yeoman 是一款有助于创建 Web 应用、生成样板代码、引入 Bowernpm 中的库以及创建包含预定义任务的 Grunt 文件的工具。

在本教程中,您将使用 Yeoman 创建一个新的基本 Web 应用,然后将 Android Studio 构建系统 (Gradle) 与 Grunt 集成,以构建 Web 应用。您还将设置 Grunt 任务以启动本地实时重新加载服务器,以便在浏览器中测试应用,这样您就不必每次更改 HTML、CSS 或 JavaScript 文件时都手动刷新页面。

前提条件

开始之前,您需要安装一些前提条件:

  1. 安装 Yeoman:https://github.com/yeoman/yeoman/wiki/Getting-Started
  2. 安装 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 中的文件合并到一起。

将网址定义为字符串资源,并在代码中使用该资源,而不是硬编码网址。

  1. 创建文件夹 src/liveserversrc/staticbuild

  2. liveserver 文件夹中,创建一个名为 res 的新文件夹,并在其中创建一个名为 values 的子文件夹。在其中创建一个名为 config.xml 的文件。对 staticbuild 文件夹重复此过程。

  3. 在配置文件中,将以下代码行添加到 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>
    
  4. 将 WebView 设置为使用这些配置文件中的 init_url

    mWebView.loadUrl(getString(R.string.init_url));
    
  5. 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 添加互联网权限。

  6. 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'**
      },
      ...
    }
    

如需测试更改,请执行以下操作:

  1. 启动实时服务器:

    grunt server
    
  2. 在 Android Studio 中,在 Build Variant 选择中,选择 LiveserverDebug。然后点击运行

    您应该能够修改 HTML、CSS 和 JavaScript 内容,并立即在浏览器中看到修改后的效果。

现在,您有两个版本的应用:一个是从 Grunt 服务器实时重新加载的开发版本;另一个是本地打包到 Android 应用中的静态版本。