Quy trình công việc của WebView

Ngày xuất bản: 28 tháng 2 năm 2014

Một trong những điều tuyệt vời khi phát triển web là bộ công cụ phong phú mà bạn có thể sử dụng để cải thiện quy trình làm việc.

Ví dụ về một trong những công cụ này là Grunt, một trình chạy tác vụ JavaScript cho phép bạn xác định các tác vụ cần thực hiện trên ứng dụng web, từ việc biên dịch Sass và khởi động máy chủ trực tiếp đến nén hình ảnh, rút gọn JavaScript và chạy JSHint trước khi tạo bản dựng sẵn sàng phát hành công khai.

Yeoman là một công cụ giúp tạo ứng dụng web, tạo bản dựng, đưa thư viện từ Bowernpm vào, đồng thời tạo tệp Grunt có các tác vụ được xác định trước.

Trong hướng dẫn này, bạn sẽ sử dụng Yeoman để tạo một ứng dụng web cơ bản mới, sau đó tích hợp hệ thống xây dựng Android Studio (Gradle) với Grunt để tạo ứng dụng web. Bạn cũng sẽ thiết lập các tác vụ Grunt để chạy máy chủ tải lại trực tiếp cục bộ nhằm kiểm thử ứng dụng trong trình duyệt. Nhờ đó, bạn không phải làm mới trang theo cách thủ công mỗi khi thay đổi tệp HTML, CSS hoặc JavaScript.

Điều kiện tiên quyết

Trước khi bắt đầu, bạn cần cài đặt một số điều kiện tiên quyết:

  1. Cài đặt Yeoman: https://github.com/yeoman/yeoman/wiki/Getting-Started
  2. Cài đặt Android Studio: https://developer.android.com/sdk/installing/studio.html

Bước 1. Tạo một dự án mới trong Android Studio bằng WebView

Bạn có thể xem hướng dẫn đầy đủ về cách thực hiện việc này trong hướng dẫn bắt đầu sử dụng.

Bước 2. Tạo thư mục con cho nội dung ứng dụng web

Sau khi tạo dự án, hãy tạo một thư mục cấp cao nhất mới. Trong Android Studio, hãy nhấp chuột phải vào thư mục dự án rồi chọn New (Mới) > Directory (Thư mục).

Đặt tên thư mục là webapp.

Bước 3. Tạo dự án Yeoman trong thư mục mới

Trong dòng lệnh cd đến thư mục webapp trong dự án.

cd <path-to-project>/webapp/

Sau đó, hãy tạo một ứng dụng web mới bằng Yeoman:

yo webapp

Làm theo lời nhắc trên màn hình để chọn các tuỳ chọn dự án. Bạn có thể cần chạy sudo npm install, tuỳ thuộc vào cách cài đặt npm trên máy.

Trước khi chuyển sang bước tiếp theo, hãy kiểm thử ứng dụng bằng cách chạy lệnh sau:

grunt server

Một thẻ mới sẽ mở trong trình duyệt, kết nối với một máy chủ cục bộ do Grunt khởi động. Nếu bạn thay đổi một trong các tệp HTML, CSS hoặc JavaScript trong dự án, trang sẽ tự động tải lại và cập nhật.

Nếu bạn chạy grunt build, một thư mục mới, dist, sẽ được tạo và ứng dụng web của bạn sẽ được nén, tối ưu hoá và tạo thành một phiên bản sẵn sàng phát hành trong thư mục này.

Bước 4. Định cấu hình bản dựng Gradle

Trong thư mục webapp, hãy tạo một tệp mới có tên là build.gradle.

Trong tệp build.gradle mới, hãy thêm nội dung sau:

import org.apache.tools.ant.taskdefs.condition.Os

task buildWebApp(type: Exec) {
  executable = Os.isFamily(Os.FAMILY_WINDOWS) ? "grunt.cmd" : "grunt"
  args = ["build"]
}

Thao tác này sẽ tạo một tác vụ mới có tên là buildWebApp với loại Exec được xác định trước. Sau đó, đặt biến executable trong Exec thành lệnh grunt có liên quan tuỳ thuộc vào hệ điều hành hiện tại. args được đặt thành "build", tương đương với việc grunt build được chạy trên dòng lệnh. Cuối cùng, lệnh nhập ở trên cùng là để sử dụng Os.isFamily(Os.FAMILY_WINDOWS).

Trước khi có thể sử dụng tác vụ mới này, chúng ta cần cho dự án biết về tệp build.gradle mới.

Mở settings.gradle trong thư mục gốc rồi thêm dòng sau:

include ':webapp'

Bước 5. Tạo ứng dụng web khi bạn tạo ứng dụng Android

Tạo ứng dụng web rồi sao chép ứng dụng đó vào thư mục assets của ứng dụng Android.

Sao chép nội dung sau vào tệp build.gradle của ứng dụng Android:

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
}

Hãy cùng tìm hiểu từng phần của mã này.

tác vụ copyWebApplication

task copyWebApplication(type: Copy) {
  from '../webapp/dist'
  into 'src/main/assets/www'
}

Tác vụ Copy này sẽ sao chép ứng dụng của bạn từ thư mục webapp/dist. Chúng ta muốn sao chép các tệp vào src/main/assets/www. Tác vụ này cũng tạo cấu trúc tệp cần thiết nếu không có thư mục bắt buộc nào.

tác vụ deleteWebApplication

task deleteWebApplication(type: Delete) {
  delete 'src/main/assets/www'
}

Tác vụ xoá này sẽ xoá tất cả tệp trong thư mục assets/www.

copyWebApplication.dependsOn

copyWebApplication.dependsOn ':webapp:buildWebApp'
copyWebApplication.dependsOn deleteWebApplication

Dòng đầu tiên của mã này cho biết copyWebApplication có phần phụ thuộc trên tác vụ buildWebApp từ tệp build.gradle của ứng dụng web.

Dòng thứ hai cho biết có một phần phụ thuộc trên tác vụ deleteWebApplication.

Nói cách khác, trước khi thực sự sao chép bất kỳ tệp nào vào thư mục assets, hãy đảm bảo chúng ta tạo ứng dụng web và cũng xoá nội dung hiện tại của thư mục assets.

android.applicationVariants.all

android.applicationVariants.all { variant ->
  tasks.getByPath(":${project.name}:assemble${variant.buildType.name.capitalize()}").dependsOn copyWebApplication
}

Tác vụ này chỉ định các phần phụ thuộc cho tất cả bản dựng của dự án, cho từng phiên bản ứng dụng. Ở đây, tác vụ này đặt phần phụ thuộc trên các tác vụ assemble để chạy copyWebApplication.

Các tác vụ assemble sẽ tập hợp kết quả của dự án, vì vậy, trước tiên, bạn cần sao chép ứng dụng web sang dự án Android.

Bước 6. Đảm bảo mọi thứ đều hoạt động

Trong Android Studio, bạn không được có thư mục assets trong thư mục src của ứng dụng Android.

Đặt WebView để sử dụng trang index.html:

mWebView.loadUrl("file:///android_asset/www/index.html");

Nhấp vào Run (Chạy) để tạo ứng dụng. Bạn sẽ thấy thư mục assets với ứng dụng web trong thư mục con www.

Bước 7. Tạo máy chủ trực tiếp và tải lại trực tiếp

Tính năng tải lại trực tiếp có thể rất hữu ích để thực hiện các thay đổi nhanh chóng cho ứng dụng web. Để bật tính năng này, bạn có thể tạo hai "phiên bản sản phẩm" cho ứng dụng: phiên bản máy chủ trực tiếp và phiên bản tĩnh, trong đó nội dung web được đóng gói vào ứng dụng Android.

Trong build.gradle của ứng dụng Android, hãy thêm các dòng sau vào cuối phần tử android:

android {
  ...
  defaultConfig {
    ...
  }
  productFlavors {
    staticbuild {
      packageName "com.google.chrome.myapplication"
    }

    liveserver {
      packageName "com.google.chrome.myapplication.liveserver"
    }
  }

}

Giờ đây, Gradle cho phép bạn tạo một phiên bản ứng dụng có tên gói máy chủ trực tiếp và một phiên bản có tên gói thông thường. Để kiểm tra xem tính năng này có hoạt động hay không, hãy nhấp vào Sync Project with Gradle Files (Đồng bộ hoá dự án với tệp Gradle) (ở thanh trên cùng bên cạnh nút Run (Chạy)).

Sau đó, hãy xem Build Variants (Biến thể bản dựng) ở góc dưới bên trái của Android Studio. Đây là phần cho bạn biết những phiên bản ứng dụng mà bạn có thể tạo.

Đối với mỗi productFlavor, có các phiên bản Gỡ lỗiPhát hành mà trình bổ trợ Android cho Gradle cung cấp cho bạn theo mặc định. Giá trị này xác định xem bản dựng sẽ là bản gỡ lỗi hay bản phát hành phù hợp để triển khai trên Cửa hàng Play.

Bây giờ, bạn có hai phiên bản, nhưng chúng chưa thực sự làm gì khác biệt.

Bước 8. Tải từ máy chủ đang hoạt động

Bây giờ, hãy định cấu hình ứng dụng của bạn để tải một URL khác tuỳ thuộc vào phiên bản sản phẩm mà bạn tạo.

Trong ứng dụng Android, các tệp phổ biến cho tất cả phiên bản sản phẩm đều nằm trong src/main. Để thêm mã hoặc tài nguyên dành riêng cho một phiên bản sản phẩm, hãy tạo một thư mục khác trong src có cùng tên với productFlavor. Khi bạn tạo bản dựng cho biến thể bản dựng đó, Gradle và trình bổ trợ Android sẽ hợp nhất các tệp bổ sung này lên trên các tệp trong src/main.

Xác định URL dưới dạng tài nguyên chuỗi và sử dụng tài nguyên đó trong mã thay vì URL được mã hoá cứng.

  1. Tạo thư mục src/liveserversrc/staticbuild.

  2. Trong thư mục liveserver, hãy tạo một thư mục mới có tên res với một thư mục con có tên values. Bên trong thư mục này, hãy tạo một tệp có tên là config.xml. Lặp lại quy trình này cho thư mục staticbuild.

  3. Bên trong tệp cấu hình, hãy thêm các dòng sau vào 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>
    

    Thêm khối sau vào 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. Đặt WebView của bạn để sử dụng init_url từ các tệp cấu hình này.

    mWebView.loadUrl(getString(R.string.init_url));
    
  5. Tạo một tệp mới có tên là AndroidManifest.xml trong liveserver/AndroidManifest.xml và thêm các dòng sau:

    <?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>
    

    Thao tác này sẽ thêm quyền truy cập Internet cho các bản dựng liveserver.

  6. Bên trong webapp/Gruntfile.js, hãy tìm:

    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: **'localhost'**
      },
      ...
    }
    

    Thay thế localhost bằng 0.0.0.0 để có thể truy cập vào máy chủ cục bộ từ mạng cục bộ:

    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: '**0.0.0.0'**
      },
      ...
    }
    

Cách kiểm thử các thay đổi:

  1. Khởi động máy chủ trực tiếp:

    grunt server
    
  2. Trong Android Studio, trong phần lựa chọn Build Variant (Biến thể bản dựng), hãy chọn LiveserverDebug. Sau đó, hãy nhấp vào Chạy.

    Bạn có thể chỉnh sửa nội dung HTML, CSS và JavaScript và thấy nội dung đó được phản ánh ngay lập tức trong trình duyệt.

Bây giờ, bạn có hai phiên bản ứng dụng: một phiên bản phát triển có tính năng tải lại trực tiếp từ máy chủ Grunt; và một phiên bản tĩnh, được đóng gói cục bộ trong ứng dụng Android.