Sử dụng Google Base và Google Gear để có trải nghiệm ngoại tuyến với hiệu suất cao

Bài viết đầu tiên trong loạt bài "Xây dựng ứng dụng Ajax tốt hơn với API Google".

Dion Almaer và Pamela Fox, Google
Tháng 6 năm 2007

Lưu ý của người chỉnh sửa: API Google Jetpack không còn hoạt động nữa.

Giới thiệu

Kết hợp Google Base với Google nhạc, chúng tôi minh hoạ cách tạo một ứng dụng có thể được sử dụng ngoại tuyến. Sau khi đọc qua bài viết này, bạn sẽ quen thuộc hơn với Google Base API cũng như hiểu cách sử dụng Google nhạc để lưu trữ cũng như truy cập các tuỳ chọn và dữ liệu người dùng.

Tìm hiểu ứng dụng

Để hiểu được ứng dụng này, trước tiên bạn phải quen thuộc với Google Base (đây là cơ sở dữ liệu lớn về các mặt hàng trong nhiều danh mục như sản phẩm, bài đánh giá, công thức, sự kiện, v.v).

Mỗi mục được chú thích bằng tiêu đề, nội dung mô tả, đường liên kết đến nguồn dữ liệu gốc (nếu có), cùng với các thuộc tính bổ sung khác nhau đối với từng loại danh mục. Google Base tận dụng lợi thế của thực tế là các mục trong cùng một danh mục có chung một tập hợp các thuộc tính – ví dụ: tất cả công thức đều có nguyên liệu. Đôi khi, các mục trên Google Base thậm chí sẽ hiển thị trong kết quả tìm kiếm từ tìm kiếm web của Google hoặc tìm kiếm sản phẩm của Google.

Ứng dụng minh hoạ của chúng tôi, Base with Akinator (Dựa trên cơ sở dữ liệu), cho phép bạn lưu trữ và hiển thị những nội dung tìm kiếm phổ biến mà bạn có thể thực hiện trên Google Tìm kiếm, chẳng hạn như tìm công thức nấu ăn có "sô cô la" (yum) hoặc quảng cáo cá nhân với quảng cáo "đi bộ trên bãi biển" (lãng mạn!). Bạn có thể coi đây là "Độc giả cơ sở của Google" cho phép bạn đăng ký các tìm kiếm và xem kết quả cập nhật khi bạn truy cập lại ứng dụng hoặc khi ứng dụng ra ngoài để tìm kiếm nguồn cấp dữ liệu cập nhật 15 phút một lần.

Các nhà phát triển muốn mở rộng ứng dụng có thể thêm nhiều tính năng hơn, chẳng hạn như cảnh báo cho người dùng khi kết quả tìm kiếm chứa kết quả mới, cho phép người dùng đánh dấu (sao) các mục yêu thích (ngoại tuyến và trực tuyến) và cho phép người dùng tìm kiếm các thuộc tính theo danh mục cụ thể như Google Base.

Sử dụng nguồn cấp dữ liệu API dữ liệu cơ sở của Google

Bạn có thể truy vấn Google Base theo phương thức lập trình với API dữ liệu Google Base, API này tuân thủ khung Google Data API. Giao thức Google Data API cung cấp giao thức đơn giản để đọc và ghi trên web, đồng thời được sử dụng trong nhiều sản phẩm của Google: Picasa, Bảng tính, Blogger, Lịch, Sổ tay và nhiều sản phẩm khác.

Định dạng API Dữ liệu của Google dựa trên XML và Giao thức xuất bản Atom, vì vậy hầu hết các tương tác đọc/ghi đều ở định dạng XML.

Ví dụ về nguồn cấp dữ liệu Google Base dựa trên API Dữ liệu Google:
http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera

Loại nguồn cấp dữ liệu snippets cung cấp cho chúng tôi nguồn cấp dữ liệu mục công khai. -/products cho phép chúng ta hạn chế nguồn cấp dữ liệu ở danh mục sản phẩm. Đồng thời, tham số bq= cho phép chúng tôi hạn chế nguồn cấp dữ liệu hơn nữa để chỉ hiển thị kết quả chứa từ khóa "máy ảnh kỹ thuật số". Nếu xem nguồn cấp dữ liệu này trong trình duyệt, bạn sẽ thấy XML chứa các nút <entry> có kết quả phù hợp. Mỗi mục chứa tác giả, tiêu đề, nội dung và các yếu tố liên kết thông thường nhưng cũng đi kèm với các thuộc tính bổ sung theo danh mục cụ thể (như "giá" cho các mặt hàng trong danh mục sản phẩm).

Do hạn chế tên miền chéo của XMLHttpRequest trong trình duyệt, chúng tôi không được phép đọc trực tiếp trong nguồn cấp dữ liệu XML từ www.google.com trong mã JavaScript của chúng tôi. Chúng tôi có thể thiết lập proxy phía máy chủ để đọc trong XML và cung cấp trở lại cho một vị trí trên cùng miền với ứng dụng, nhưng chúng tôi muốn tránh hoàn toàn việc lập trình phía máy chủ. Thật may là có một cách khác.

Giống như các API Dữ liệu khác của Google, Google Base API có dữ liệu đầu ra JSON, ngoài XML chuẩn. Kết quả của nguồn cấp dữ liệu mà chúng ta thấy trước đó ở định dạng JSON sẽ có tại URL này:
http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera&alt=json

JSON là một định dạng trao đổi nhẹ cho phép lồng ghép phân cấp cũng như nhiều loại dữ liệu. Nhưng quan trọng hơn, đầu ra JSON là chính mã JavaScript gốc và do đó, nó có thể được tải vào trang web của bạn chỉ bằng cách tham chiếu nó trong thẻ tập lệnh, bỏ qua hạn chế trên nhiều miền.

API Dữ liệu của Google cũng cho phép bạn chỉ định đầu ra "json-in-script" với hàm gọi lại để thực thi sau khi JSON được tải. Điều này giúp bạn dễ dàng sử dụng đầu ra JSON hơn, vì chúng tôi có thể tự động gắn các thẻ tập lệnh vào trang và chỉ định các hàm gọi lại cho mỗi hàm.

Do đó, để tự động tải nguồn cấp dữ liệu JSON API vào cơ sở vào trang, chúng ta có thể sử dụng hàm sau để tạo thẻ tập lệnh với URL của nguồn cấp dữ liệu (được thêm vào giá trị altcallback) và thêm vào trang.

function getJSON() {
  var script = document.createElement('script');

  var url = "http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera";
  script.setAttribute('src', url + "&alt=json-in-script&callback=listResults");
  script.setAttribute('type', 'text/JavaScript');
  document.documentElement.firstChild.appendChild(script);
}

Vì vậy, hàm gọi lại listResults của chúng ta hiện có thể lặp lại qua JSON được truyền vào dưới dạng thông tin tham số và thông tin hiển thị duy nhất trên mỗi mục nhập có trong danh sách có dấu đầu dòng.

  function listTasks(root) {
    var feed = root.feed;
    var html = [''];
    html.push('<ul>');
    for (var i = 0; i < feed.entry.length; ++i) {
      var entry = feed.entry[i];
      var title = entry.title.$t;
      var content = entry.content.$t;
      html.push('<li>', title, ' (', content, ')</li>');
    }
    html.push('</ul>');

    document.getElementById("agenda").innerHTML = html.join("");
  }

Thêm Google Jetpack

Giờ đây, chúng tôi có một ứng dụng có thể trò chuyện với Google Base thông qua Google Data API, chúng tôi muốn cho phép ứng dụng này chạy ngoại tuyến. Đây cũng chính là lúc Google Jetpack ra đời.

Có nhiều lựa chọn về kiến trúc khi viết một ứng dụng có thể không có kết nối mạng. Bạn sẽ tự hỏi những câu hỏi về cách hoạt động của ứng dụng trực tuyến và ngoại tuyến (ví dụ: Ứng dụng có hoạt động giống hệt nhau không? Một số tính năng có bị tắt không, chẳng hạn như tìm kiếm? Bạn sẽ xử lý việc đồng bộ hoá như thế nào?)

Trong trường hợp của mình, chúng tôi muốn đảm bảo rằng người dùng trên các trình duyệt không có Jetpack vẫn có thể dùng ứng dụng, trong khi vẫn cung cấp cho người dùng các trình bổ trợ có lợi ích là chế độ sử dụng ngoại tuyến và một giao diện người dùng thích ứng hơn.

Cấu trúc của chúng tôi có dạng như sau:

  • Chúng tôi có một đối tượng JavaScript chịu trách nhiệm lưu trữ các truy vấn tìm kiếm của bạn và trả lại kết quả từ các truy vấn này.
  • Nếu đã cài đặt Google Jetpack, bạn sẽ nhận được phiên bản Jetpack lưu trữ mọi thứ trong cơ sở dữ liệu cục bộ.
  • Nếu chưa cài đặt Google Jetpack, bạn sẽ nhận được phiên bản lưu trữ truy vấn trong cookie và hoàn toàn không lưu trữ kết quả (do đó tốc độ phản hồi chậm hơn một chút), do kết quả quá lớn nên không thể lưu trữ trong cookie.
Thật tuyệt vời là bạn không cần phải kiểm tra if (online) {} trên toàn bộ cửa hàng. Thay vào đó, ứng dụng có một quá trình kiểm tra Bánh răng và sử dụng đúng bộ chuyển đổi.


Sử dụng cơ sở dữ liệu cục bộ của Jetpack

Một trong những thành phần của Jetpack là cơ sở dữ liệu SQLite cục bộ được nhúng và sẵn sàng để sử dụng. Có một API cơ sở dữ liệu đơn giản mà bạn sẽ thấy quen thuộc nếu trước đây bạn đã sử dụng API cho cơ sở dữ liệu phía máy chủ như MySQL hoặc Oracle.

Các bước để sử dụng cơ sở dữ liệu cục bộ khá đơn giản:

  • Khởi chạy các đối tượng của Google Jetpack
  • Lấy đối tượng gốc của cơ sở dữ liệu và mở cơ sở dữ liệu
  • Bắt đầu thực thi các yêu cầu SQL

Hãy cùng tìm hiểu nhanh.


Khởi chạy đối tượng Google Jetpack

Ứng dụng của bạn phải đọc trực tiếp nội dung của /gears/samples/gears_init.js hoặc dán mã vào tệp JavaScript của riêng bạn. Sau khi <script src="..../gears_init.js" type="text/JavaScript"></script>, bạn có quyền truy cập vào không gian tên google.wheel.


Nhận đối tượng nhà máy cơ sở dữ liệu và mở cơ sở dữ liệu
var db = google.gears.factory.create('beta.database', '1.0');
db.open('testdb');

Lệnh gọi một lần này sẽ cung cấp cho bạn một đối tượng cơ sở dữ liệu cho phép bạn mở giản đồ cơ sở dữ liệu. Khi bạn mở cơ sở dữ liệu, cơ sở dữ liệu này nằm trong cùng quy tắc chính sách nguồn gốc, vì vậy, "testdb" của bạn sẽ không xung đột với "testdb".


Bắt đầu thực thi các yêu cầu SQL

Bây giờ, chúng ta đã sẵn sàng gửi yêu cầu SQL đến cơ sở dữ liệu. Khi gửi yêu cầu "chọn", chúng tôi sẽ nhận lại một tập hợp kết quả mà chúng tôi có thể lặp lại đối với dữ liệu mong muốn:

var rs = db.execute('select * from foo where name = ?', [ name ]);

Bạn có thể thao tác trên tập hợp kết quả được trả về bằng các phương thức sau:

booleanisValidRow()
voidnext()
voidclose()
intfieldCount()
stringfieldName(int fieldIndex)
variantfield(int fieldIndex)
variantfieldByName(string fieldname)

Để biết thêm thông tin, vui lòng xem tài liệu về API Mô-đun cơ sở dữ liệu. (Lưu ý của người chỉnh sửa: Google SLA API không còn hoạt động nữa).


Sử dụng JetpackDB để đóng gói API cấp thấp

Chúng tôi muốn gói gọn và tạo điều kiện thuận lợi hơn cho một số tác vụ cơ sở dữ liệu phổ biến. Ví dụ:

  • Chúng tôi muốn có một cách tuyệt vời để ghi lại SQL được tạo khi chúng tôi gỡ lỗi ứng dụng.
  • Chúng ta muốn xử lý các trường hợp ngoại lệ ở một nơi thay vì phải try{}catch(){} trên toàn bộ địa điểm.
  • Chúng ta muốn xử lý các đối tượng JavaScript thay vì các tập hợp kết quả khi đọc hoặc ghi dữ liệu.

Để xử lý các vấn đề này theo cách chung, chúng tôi đã tạo GearsDB, một thư viện nguồn mở bao gồm đối tượng Cơ sở dữ liệu. Bây giờ chúng tôi sẽ hướng dẫn bạn cách sử dụng JetpackDB.

Thiết lập ban đầu

Trong mã window.onload của chúng ta, cần phải đảm bảo rằng các bảng cơ sở dữ liệu mà chúng ta sử dụng dựa trên vị trí. Nếu người dùng đã cài đặt Jetpack khi mã sau đây chạy, họ sẽ tạo một đối tượng GearsBaseContent:

content = hasGears() ? new GearsBaseContent() : new CookieBaseContent();

Tiếp theo, chúng ta mở cơ sở dữ liệu và tạo bảng nếu chúng chưa tồn tại:

db = new GearsDB('gears-base'); // db is defined as a global for reuse later!

if (db) {
  db.run('create table if not exists BaseQueries' +
         ' (Phrase varchar(255), Itemtype varchar(100))');
  db.run('create table if not exists BaseFeeds' + 
         ' (id varchar(255), JSON text)');
}

Đến thời điểm này, chúng tôi chắc chắn có bảng để lưu trữ các truy vấn và nguồn cấp dữ liệu. Mã new GearsDB(name) sẽ đóng gói phần mở đầu của cơ sở dữ liệu với tên đã đặt. Phương thức run gói phương thức execute ở cấp thấp hơn nhưng cũng xử lý đầu ra gỡ lỗi vào một bảng điều khiển và giữ lại các ngoại lệ.


Thêm cụm từ tìm kiếm

Khi mới chạy ứng dụng, bạn sẽ không có lượt tìm kiếm nào. Nếu bạn cố gắng tìm kiếm Nintendo Wii trong các sản phẩm, chúng tôi sẽ lưu cụm từ tìm kiếm này trong bảng BaseQuery.

Phiên bản Jetpack của phương thức addQuery thực hiện việc này bằng cách lấy thông tin đầu vào và lưu thông qua insertRow:

var searchterm = { Phrase: phrase, Itemtype: itemtype };
db.insertRow('BaseQueries', searchterm); 

insertRow lấy một đối tượng JavaScript (searchterm) và xử lý việc INSERT đối tượng đó vào bảng cho bạn. Mã này cũng cho phép bạn xác định các quy tắc ràng buộc (ví dụ: chèn khối duy nhất của nhiều "Bob"). Tuy nhiên, trong hầu hết các trường hợp, bạn sẽ xử lý các hạn chế này trong chính cơ sở dữ liệu.


Nhận Tất cả các cụm từ tìm kiếm

Để điền danh sách tìm kiếm trước đây của bạn, chúng tôi sử dụng một trình bao bọc chọn lọc có tên selectAll:

GearsBaseContent.prototype.getQueries = function() {
  return this.db.selectAll('select * from BaseQueries');
}

Thao tác này sẽ trả về một loạt các đối tượng JavaScript khớp với các hàng trong cơ sở dữ liệu (ví dụ: [ { Phrase: 'Nintendo Wii', Itemtype: 'product' }, { ... }, ...]).

Trong trường hợp này, bạn có thể trả về danh sách đầy đủ. Nhưng nếu bạn có nhiều dữ liệu, bạn có thể muốn sử dụng lệnh gọi lại trong lệnh gọi để bạn có thể thao tác trên từng hàng được trả về như trong:

 db.selectAll('select * from BaseQueries where Itemtype = ?', ['product'], function(row) {
  ... do something with this row ...
});

Dưới đây là một số phương thức chọn hữu ích khác trong JetpackDB:

selectOne(sql, args)Trả về đối tượng JavaScript đầu tiên/một phù hợp
selectRow(table, where, args, select)Thường được sử dụng trong các trường hợp đơn giản để bỏ qua SQL
selectRows(table, where, args, callback, select)Giống như selectRow, nhưng cho nhiều kết quả.

Tải nguồn cấp dữ liệu

Khi nhận được nguồn cấp dữ liệu kết quả từ Google Base, chúng tôi cần lưu nguồn cấp này vào cơ sở dữ liệu:

content.setFeed({ id: id, JSON: json.toJSONString() });

... which calls ...

GearsBaseContent.prototype.setFeed = function(feed) {
  this.db.forceRow('BaseFeeds', feed);
}

Trước tiên, chúng ta lấy nguồn cấp dữ liệu JSON và trả về dưới dạng Chuỗi bằng phương thức toJSONString. Sau đó, chúng ta sẽ tạo đối tượng feed và truyền đối tượng đó vào phương thức forceRow. forceRow sẽ CHÈN mục nhập nếu chưa có mục nào hoặc CẬP NHẬT một mục hiện có.


Hiển thị kết quả tìm kiếm

Ứng dụng của chúng tôi hiển thị kết quả cho một tìm kiếm cụ thể trên bảng điều khiển bên phải của trang. Sau đây là cách chúng tôi truy xuất nguồn cấp dữ liệu liên kết với cụm từ tìm kiếm:

GearsBaseContent.prototype.getFeed = function(url) {
  var row = this.db.selectRow('BaseFeeds', 'id = ?', [ url ]);
  return row.JSON;
}

Bây giờ, chúng ta đã có JSON cho một hàng, chúng ta có thể eval() để tải lại các đối tượng:

eval("var json = " + jsonString + ";");

Chúng ta đã thoát khỏi cuộc đua và có thể bắt đầu nội dung HTML từ JSON vào trang của mình.


Sử dụng Kho lưu trữ tài nguyên để truy cập ngoại tuyến

Vì chúng tôi đang lấy nội dung từ một cơ sở dữ liệu cục bộ nên ứng dụng này cũng phải hoạt động ở chế độ ngoại tuyến, đúng không?

Vâng, không. Vấn đề là để khởi động ứng dụng này, bạn cần phải tải các tài nguyên web của ứng dụng đó, chẳng hạn như JavaScript, CSS, HTML và hình ảnh của ứng dụng. Hiện tại, nếu người dùng của bạn đã thực hiện các bước sau, ứng dụng vẫn có thể hoạt động: khởi động trực tuyến, thực hiện một số tìm kiếm, không đóng trình duyệt, chuyển sang ngoại tuyến. Chức năng này có thể hoạt động vì các mục vẫn sẽ nằm trong bộ nhớ đệm của trình duyệt. Nhưng nếu điều này không đúng thì sao? Chúng ta muốn người dùng của mình có thể truy cập vào ứng dụng từ đầu, sau khi khởi động lại, v.v.

Để làm việc này, chúng tôi sử dụng thành phần LocalServer và thu thập tài nguyên của mình. Khi bạn thu thập tài nguyên (chẳng hạn như HTML và JavaScript cần thiết để chạy ứng dụng), GTIN sẽ lưu những mục này và cũng sẽ chặn các yêu cầu từ trình duyệt để trả lại chúng. Máy chủ cục bộ sẽ hoạt động như một cảnh báo lưu lượng truy cập và trả về nội dung đã lưu từ cửa hàng.

Chúng tôi cũng sử dụng thành phần ResourceStore. Thành phần này yêu cầu bạn phải cho hệ thống biết tệp bạn muốn thu thập theo cách thủ công. Trong nhiều trường hợp, bạn muốn tạo phiên bản cho ứng dụng và cho phép nâng cấp theo cách giao dịch. Một tập hợp các tài nguyên cùng nhau xác định một phiên bản và khi phát hành một tập hợp tài nguyên mới, bạn sẽ muốn người dùng của mình nâng cấp các tệp một cách liền mạch. Nếu đó là mô hình của bạn, bạn sẽ sử dụng API ManagedResourceStore.

Để thu thập tài nguyên của chúng ta, đối tượng JetpackBaseContent sẽ:

  1. Thiết lập một mảng tệp cần thu thập
  2. Tạo Máy chủ cục bộ
  3. Mở hoặc tạo ResourceStore mới
  4. Gọi để chụp các trang vào cửa hàng
// Step 1
this.storeName = 'gears-base';
this.pageFiles = [
  location.pathname,
  'gears_base.js',
  '../scripts/gears_db.js',
  '../scripts/firebug/firebug.js',
  '../scripts/firebug/firebug.html',
  '../scripts/firebug/firebug.css',
  '../scripts/json_util.js',    'style.css',
  'capture.gif' ];

// Step 2
try {
  this.localServer = google.gears.factory.create('beta.localserver', '1.0');
} catch (e) {
  alert('Could not create local server: ' + e.message);
  return;
}

// Step 3
this.store = this.localServer.openStore(this.storeName) || this.localServer.createStore(this.storeName);

// Step 4
this.capturePageFiles();

... which calls ...

GearsBaseContent.prototype.capturePageFiles = function() {
  this.store.capture(this.pageFiles, function(url, success, captureId) {
    console.log(url + ' capture ' + (success ? 'succeeded' : 'failed'));
  });
}

Điều quan trọng cần lưu ý ở đây là bạn chỉ có thể thu thập tài nguyên trên miền của riêng mình. Chúng tôi gặp phải hạn chế này khi cố gắng truy cập vào tệp JavaScript MavenDB trực tiếp từ tệp " bánh_db.js " ban đầu trong đường dây SVN của tệp. Giải pháp này tất nhiên là rất đơn giản: bạn cần tải xuống bất kỳ tài nguyên bên ngoài nào và đặt chúng trong miền của bạn. Lưu ý rằng lệnh chuyển hướng 302 hoặc 301 sẽ không hoạt động, vì LocalServer chỉ chấp nhận mã máy chủ 200 (Thành công) hoặc 304 (Không sửa đổi).

Điều này ảnh hưởng đến kết quả. Nếu bạn đặt hình ảnh lên images.yourdomain.com, bạn sẽ không thể chụp chúng. www1 và www2 không thể nhìn thấy nhau. Bạn có thể thiết lập proxy phía máy chủ, nhưng việc này sẽ phá vỡ mục đích chia tách ứng dụng của bạn thành nhiều miền.

Gỡ lỗi ứng dụng ngoại tuyến

Gỡ lỗi ứng dụng ngoại tuyến hơi phức tạp hơn một chút. Hiện có nhiều tình huống cần kiểm thử hơn:

  • Tôi đang kết nối mạng với ứng dụng hoàn toàn chạy trong bộ nhớ đệm
  • Tôi đang trực tuyến nhưng không truy cập được ứng dụng và không có tệp nào trong bộ nhớ đệm
  • Tôi hiện không có kết nối mạng nhưng đã truy cập vào ứng dụng
  • Tôi hiện không có kết nối mạng và chưa từng truy cập vào ứng dụng (đây không phải là một nơi thích hợp)

Để giúp cuộc sống dễ dàng hơn, chúng tôi đã sử dụng mẫu sau:

  • Chúng tôi tắt bộ nhớ đệm trong Firefox (hoặc trình duyệt bạn chọn) khi cần đảm bảo rằng trình duyệt đó không chỉ lấy nội dung từ bộ nhớ đệm
  • Chúng tôi gỡ lỗi bằng Trekker (và Trekker Lite để kiểm tra trên các trình duyệt khác); chúng tôi sử dụng console.log() trên toàn bộ nền tảng và phát hiện cho bảng điều khiển chỉ trong trường hợp
  • Chúng tôi thêm mã JavaScript của trình trợ giúp vào:
    • cho phép chúng tôi xoá cơ sở dữ liệu và cung cấp cho chúng tôi một phương tiện
    • xoá các tệp đã thu thập, do đó khi bạn tải lại, nó sẽ được đưa lên Internet để tải lại chúng (hữu ích khi bạn lặp lại quá trình phát triển ;)

Tiện ích gỡ lỗi chỉ hiển thị ở bên trái trang nếu bạn đã cài đặt Jetpack. Đoạn mã này có chú thích để xóa mã:

GearsBaseContent.prototype.clearServer = function() {
  if (this.localServer.openStore(this.storeName)) {
    this.localServer.removeStore(this.storeName);
    this.store = null;
  }
}

GearsBaseContent.prototype.clearTables = function() {
  if (this.db) {
    this.db.run('delete from BaseQueries');
    this.db.run('delete from BaseFeeds');
  }
  displayQueries();
}

Kết luận

Bạn có thể thấy rằng hoạt động với Google Jetpack thực sự khá đơn giản. Chúng tôi đã sử dụng JetpackDB để làm cho thành phần Cơ sở dữ liệu trở nên dễ dàng hơn nữa, đồng thời sử dụng ResourceStore thủ công vốn hoạt động tốt trong ví dụ của chúng tôi.

Lĩnh vực mà bạn dành nhiều thời gian nhất để xác định chiến lược xác định thời điểm tải dữ liệu trực tuyến và cách lưu trữ dữ liệu đó ngoại tuyến. Bạn cần dành thời gian để xác định giản đồ cơ sở dữ liệu. Nếu cần thay đổi giản đồ trong tương lai, bạn sẽ cần phải quản lý sự thay đổi đó vì người dùng hiện tại của bạn đã có phiên bản cơ sở dữ liệu. Điều này có nghĩa là bạn sẽ cần gửi mã tập lệnh cùng với mọi bản nâng cấp db. Rõ ràng là bạn nên giảm thiểu điều này. Bạn nên dùng thử GearShift, một thư viện nhỏ có thể giúp bạn quản lý các bản sửa đổi.

Chúng tôi cũng có thể sử dụng ManagedResourceStore để theo dõi các tệp của mình, với những hậu quả sau:

  • Chúng tôi sẽ là công dân gương mẫu và tạo các phiên bản của chúng tôi để giúp chúng tôi nâng cấp rõ ràng trong tương lai
  • Có một tính năng của ManagedResourceStore cho phép bạn đặt bí danh cho một URL xuất hiện trong một nội dung khác. Lựa chọn kiến trúc hợp lệ là wheel_base.js không phải là phiên bản cải tiến và bí danh, vì vậy, chính DSA sẽ tải xuống wheel_base_withgear.js để hỗ trợ ngoại tuyến.
Đối với ứng dụng, chúng tôi cảm thấy việc có một giao diện và triển khai giao diện đó dễ dàng hơn theo 2 cách.

Chúng tôi hy vọng bạn thấy việc chuẩn bị cho ứng dụng thật dễ dàng và thú vị! Vui lòng tham gia diễn đàn Google Jetpack của chúng tôi nếu bạn có câu hỏi hoặc một ứng dụng muốn chia sẻ.