Thông tin mới về Web In Play

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

Kể từ khi Hoạt động đáng tin cậy trên web được ra mắt, nhóm Chrome đã giúp việc sử dụng Bubblewrap trở nên dễ dàng hơn. Chúng tôi đã bổ sung các tính năng khác, chẳng hạn như tích hợp Google Play Billing và cho phép tính năng này hoạt động trên nhiều nền tảng hơn, chẳng hạn như ChromeOS.

Các tính năng của Bubblewrap và Hoạt động đáng tin cậy trên web

Bubblewrap giúp bạn tạo các ứng dụng khởi chạy PWA bên trong Hoạt động đáng tin cậy trên web mà không cần có kiến thức về công cụ dành riêng cho nền tảng.

Quy trình thiết lập đơn giản

Trước đây, để sử dụng Bubblewrap, bạn phải thiết lập Bộ phát triển Java và SDK Android theo cách thủ công. Cả hai đều dễ xảy ra lỗi. Giờ đây, công cụ này sẽ tự động tải các phần phụ thuộc bên ngoài xuống khi chạy lần đầu tiên.

Bạn vẫn có thể chọn sử dụng một bản cài đặt hiện có của các phần phụ thuộc nếu muốn, và lệnh doctor mới sẽ giúp tìm ra vấn đề và đề xuất cách khắc phục cho cấu hình. Giờ đây, bạn có thể cập nhật cấu hình từ dòng lệnh bằng lệnh updateConfig.

Trình hướng dẫn được cải tiến

Khi tạo dự án bằng init, Bubblewrap cần thông tin để tạo ứng dụng Android. Công cụ này trích xuất các giá trị từ Tệp kê khai ứng dụng web và cung cấp các giá trị mặc định nếu có thể.

Bạn có thể thay đổi các giá trị đó khi tạo dự án mới, nhưng trước đây ý nghĩa của từng trường không rõ ràng. Các hộp thoại khởi động đã được tạo lại với nội dung mô tả và quy trình xác thực tốt hơn cho từng trường nhập dữ liệu.

Hỗ trợ chế độ hiển thị toàn màn hình và hướng màn hình

Trong một số trường hợp, bạn có thể muốn ứng dụng của mình sử dụng càng nhiều màn hình càng tốt và khi xây dựng PWA, bạn có thể triển khai việc này bằng cách đặt trường display từ Tệp kê khai ứng dụng web thành fullscreen.

Khi Bubblewrap phát hiện tuỳ chọn toàn màn hình trong Tệp kê khai ứng dụng web, công cụ này sẽ định cấu hình ứng dụng Android để khởi chạy ở chế độ toàn màn hình hoặc chế độ hiển thị tối đa, theo thuật ngữ dành riêng cho Android.

Trường orientation trong Tệp kê khai ứng dụng web xác định xem ứng dụng có nên được khởi động ở chế độ dọc, chế độ ngang hay theo hướng mà thiết bị đang sử dụng hay không. Bubblewrap hiện đọc trường Tệp kê khai ứng dụng web và sử dụng trường này làm giá trị mặc định khi tạo ứng dụng Android.

Bạn có thể tuỳ chỉnh cả hai cấu hình trong quy trình bubblewrap init.

Kết quả đầu ra của AppBundle

App Bundle là một định dạng phát hành cho các ứng dụng uỷ quyền việc tạo và ký tệp APK cuối cùng cho Play. Trên thực tế, điều này cho phép phân phát các tệp nhỏ hơn cho người dùng khi tải ứng dụng xuống từ cửa hàng.

Bubblewrap hiện đóng gói ứng dụng dưới dạng Gói ứng dụng, trong một tệp có tên là app-release-bundle.aab. Bạn nên ưu tiên định dạng này khi phát hành ứng dụng lên Cửa hàng Play, vì đây là định dạng bắt buộc của cửa hàng kể từ năm 2021.

Uỷ quyền vị trí địa lý

Người dùng mong muốn các ứng dụng được cài đặt trên thiết bị của họ hoạt động nhất quán, bất kể công nghệ. Khi được dùng trong Hoạt động đáng tin cậy trên web, quyền GeoLocation hiện có thể được uỷ quyền cho Hệ điều hành. Khi quyền này được bật, người dùng sẽ thấy các hộp thoại giống như ứng dụng được xây dựng bằng Kotlin hoặc Java, đồng thời tìm thấy các chế độ kiểm soát để quản lý quyền ở cùng một nơi.

Bạn có thể thêm tính năng này thông qua Bubblewrap và vì tính năng này thêm các phần phụ thuộc bổ sung vào dự án Android, nên bạn chỉ nên bật tính năng này khi ứng dụng web đang sử dụng quyền Vị trí địa lý.

Tệp nhị phân được tối ưu hoá

Thiết bị có bộ nhớ hạn chế thường phổ biến ở một số khu vực trên thế giới và chủ sở hữu của những thiết bị đó thường thích các ứng dụng nhỏ hơn. Các ứng dụng sử dụng Hoạt động đáng tin cậy trên web tạo ra các tệp nhị phân nhỏ, giúp người dùng bớt lo lắng.

Bubblewrap đã được tối ưu hoá bằng cách giảm danh sách các thư viện Android cần thiết, nhờ đó, các tệp nhị phân được tạo sẽ nhỏ hơn 800k. Trên thực tế, con số này chưa bằng một nửa kích thước trung bình do các phiên bản trước tạo ra. Để tận dụng các tệp nhị phân nhỏ hơn, bạn chỉ cần cập nhật ứng dụng bằng phiên bản Bubblewrap mới nhất.

Cách cập nhật ứng dụng hiện có

Ứng dụng do Bubblewrap tạo ra bao gồm một ứng dụng web và một trình bao bọc Android gọn nhẹ để mở PWA. Mặc dù PWA mở bên trong Hoạt động đáng tin cậy trên web tuân theo cùng một chu kỳ cập nhật như mọi ứng dụng web, nhưng trình bao bọc gốc có thể và nên được cập nhật.

Bạn nên cập nhật ứng dụng để đảm bảo ứng dụng đang sử dụng phiên bản trình bao bọc mới nhất, có các bản sửa lỗi và tính năng mới nhất. Khi cài đặt phiên bản Bubblewrap mới nhất, lệnh update sẽ áp dụng phiên bản trình bao bọc mới nhất cho một dự án hiện có:

npm update -g @bubblewrap/cli
bubblewrap update
bubblewrap build

Một lý do khác để cập nhật các ứng dụng đó là đảm bảo rằng các thay đổi đối với Tệp kê khai web được áp dụng cho ứng dụng. Hãy sử dụng lệnh merge mới cho việc đó:

bubblewrap merge
bubblewrap update
bubblewrap build

Nội dung cập nhật về Tiêu chí chất lượng

Chrome 86 đã đưa ra những thay đổi đối với Tiêu chí chất lượng của Hoạt động đáng tin cậy trên web. Những thay đổi này được giải thích đầy đủ trong bài viết Thay đổi đối với tiêu chí chất lượng cho PWA sử dụng Hoạt động đáng tin cậy trên web.

Tóm lại, bạn nên đảm bảo ứng dụng của mình xử lý các trường hợp sau để tránh gặp sự cố:

  • Không xác minh được đường liên kết đến tài sản kỹ thuật số khi chạy ứng dụng
  • Không trả về được HTTP 200 cho yêu cầu tài nguyên mạng ngoại tuyến
  • Trả về lỗi HTTP 404 hoặc 5xx trong ứng dụng.

Ngoài việc đảm bảo rằng ứng dụng vượt qua quy trình Xác thực đường liên kết đến tài sản kỹ thuật số, các trường hợp còn lại có thể được xử lý bằng một trình chạy dịch vụ:

self.addEventListener('fetch', event => {
  event.respondWith((async () => {
    try {
      return await fetchAndHandleError(event.request);
    } catch {
      // Failed to load from the network. User is offline or the response
      // has a status code that triggers the Quality Criteria.
      // Try loading from cache.
      const cachedResponse = await caches.match(event.request);
      if (cachedResponse) {
        return cachedResponse;
      }
      // Response was not found on the cache. Send the error / offline
      // page. OFFLINE_PAGE should be pre-cached when the service worker
      // is activated.
      return await caches.match(OFFLINE_PAGE);
    }
  })());
});

async function fetchAndHandleError(request) {
  const cache = await caches.open(RUNTIME_CACHE);
  const response = await fetch(request);

  // Throw an error if the response returns one of the status
  // that trigger the Quality Criteria.
  if (response.status === 404 ||
      response.status >= 500 && response.status < 600) {
    throw new Error(`Server responded with status: ${response.status}`);
  }

  // Cache the response if the request is successful.
  cache.put(request, response.clone());
  return response;
}

Workbox áp dụng các phương pháp hay nhất và loại bỏ mã nguyên mẫu khi sử dụng trình chạy dịch vụ. Ngoài ra, hãy cân nhắc sử dụng trình bổ trợ Workbox để xử lý các trường hợp đó:

export class FallbackOnErrorPlugin {
  constructor(offlineFallbackUrl, notFoundFallbackUrl, serverErrorFallbackUrl) {
    this.notFoundFallbackUrl = notFoundFallbackUrl;
    this.offlineFallbackUrl = offlineFallbackUrl;
    this.serverErrorFallbackUrl = serverErrorFallbackUrl;
  }

  checkTrustedWebActivityCrash(response) {
    if (response.status === 404 || response.status >= 500 && response.status <= 600) {
      const type = response.status === 404 ? 'E_NOT_FOUND' : 'E_SERVER_ERROR';
      const error = new Error(`Invalid response status (${response.status})`);
      error.type = type;
      throw error;
    }
  }

  // This is called whenever there's a network response,
  // but we want special behavior for 404 and 5**.
  fetchDidSucceed({response}) {
    // Cause a crash if this is a Trusted Web Activity crash.
    this.checkTrustedWebActivityCrash(response);

    // If it's a good response, it can be used as-is.
    return response;
  }

  // This callback is new in Workbox v6, and is triggered whenever
  // an error (including a NetworkError) is thrown when a handler runs.
  handlerDidError(details) {
    let fallbackURL;
    switch (details.error.details.error.type) {
      case 'E_NOT_FOUND': fallbackURL = this.notFoundFallbackUrl; break;
      case 'E_SERVER_ERROR': fallbackURL = this.serverErrorFallbackUrl; break;
      default: fallbackURL = this.offlineFallbackUrl;
    }

    return caches.match(fallbackURL, {
      // Use ignoreSearch as a shortcut to work with precached URLs
      // that have _WB_REVISION parameters.
      ignoreSearch: true,
    });
  }
}