Các dịch vụ đám mây của Parse dành cho Android

Lưu trữ và truy vấn người dùng, các đối tượng dữ liệu và các tệp trong đám mây cho các ứng dụng Android của bạn

Khám phá những ưu điểm về lưu trữ dữ liệu của ứng dụng di động trong một đám mây riêng thông qua bài giới thiệu về Parse SDK (Bộ công cụ dùng cho nhà phát triển phần mềm của Parse) này, phiên bản dành cho Android. Chuyên gia di động C. Enrique Ortiz giới thiệu các lớp API của Parse để lưu trữ và xử lý người dùng, các đối tượng dữ liệu và các tệp trong đám mây cho các ứng dụng di động của bạn.

C. Enrique Ortiz, Chuyên gia công nghệ di động, Independent

C. Enrique Ortiz là một chuyên gia có nhiều kinh nghiệm làm việc trong lĩnh vực di động. Ông còn là tác giả và là một blogger. Ông từng viết ra các ứng dụng di động từ đầu đến cuối, kể cả trước khi xuất hiện các dòng điện thoại thông minh. Ông đã có nhiều bài báo kỹ thuật, viết hai quyển sách về phát triển phần mềm di động và ông đã giúp hàng chục công ty về các nhu cầu điện toán di động của họ.


Cấp độ đóng góp cho developerWorks của
        tác giả

03 05 2013

Bộ công cụ cho nhà phát triển phần mềm di động của Parse (Parse mobile SDK) cung cấp các API và các dịch vụ đám mây dành cho các ứng dụng iOS, Android và Windows®. Parse SDK còn cung cấp một JavaScript và các API REST. Khi sử dụng Parse API, bạn có thể chạy các ứng dụng di động của mình trên đám mây một cách nhanh chóng và hao tốn ít hiệu năng. Một ứng dụng di động được tích hợp với Parse API có thể dễ dàng lưu trữ các đối tượng và các tệp dữ liệu trên Parse cloud, gửi và lắng nghe các tin nhắn push (ND.: tin nhắn push (push notification) cho phép một ứng dụng thông báo cho bạn các tin nhắn hoặc sự kiện mới mà không cần phải mở ứng dụng ra), quản lý người dùng, xử lý dữ liệu vị trí địa lý và sử dụng các nền tảng truyền thông xã hội như Twitter và Facebook. Đối với các ứng dụng di động cần mở rộng quy mô, Parse SDK cung cấp tất cả tính co giãn của một nền tảng đám mây.

Trước khi bắt đầu

Đối với bài này tôi cho rằng bạn đã quen thuộc với các khái niệm cơ bản cần thiết để lập trình ứng dụng di động với JSON, Android và Eclipse. Trước khi tiếp tục, bạn hãy vào trang Parse.com và khai báo ứng dụng của mình. Chỉ cần làm theo các hướng dẫn đơn giản bắt đầu từ trang đăng ký.

Bài này giới thiệu các lớp Parse API cốt lõi cho người dùng, các đối tượng dữ liệu và các tệp của Parse. Bạn sẽ tìm hiểu cách làm việc với các danh sách kiểm soát truy cập (ACL), cách thực hiện các thao tác CRUD trên các đối tượng dữ liệu, cách lưu trữ và lấy ra các tệp trong Parse cloud. Các ví dụ được xây dựng trên Parse SDK cho Android (xem phần Tài nguyên).

Bảng điều khiển Parse

Bảng điều khiển Parse hỗ trợ các nhà phát triển trong việc quản lý các ứng dụng. Bảng điều khiển cung cấp các số liệu thống kê về cách sử dụng chung và cách sử dụng ứng dụng-đặc trưng cho các API, các tệp và các tin nhắn push. Các khóa và các giá trị thiết lập ứng dụng được quản lý thông qua bảng điều khiển. Bảng điều khiển này cũng cung cấp một trình duyệt dữ liệu để cho phép các nhà phát triển duyệt và thậm chí chỉnh sửa các đối tượng Parse đã lưu. Trình duyệt dữ liệu rất có ích cho việc gỡ lỗi. Hình 1 là một ảnh chụp màn hình của bảng điều khiển Parse:

Hình 1. Bảng điều khiển Parse
Một ảnh chụp nhanh của bảng điều khiển Parse.

Các ứng dụng được xác thực thông qua một Application ID (mã định danh ứng dụng) và một Client ID (mã định danh khách hàng). Để có được các ID ứng dụng và ID khách hàng của mình, bạn phải đăng ký ứng dụng của mình qua bảng điều khiển Parse. Bạn sẽ sử dụng các khóa này khi khởi tạo thư viện Parse trên ứng dụng của mình.

Các đối tượng dữ liệu Parse

Trong Parse, dữ liệu được biểu diễn bằng cách sử dụng ParseObject, một đối tượng chứa các cặp name-value (tên-giá trị). ParseObject có thể lưu trữ bất kỳ dữ liệu nào tương thích với JSON, như trong Liệt kê 1 1:

Liệt kê 1. Một ví dụ về ParseObject
ParseObject myParseObject = new ParseObject("MyObject"); // Class Name
myParseObject.put("name", "C. Enrique Ortiz");
myParseObject.put("twitterHandle", "eortiz");
myParseObject.put("followers", 123456);

Khi được tạo ra, ParseObject được cấp một classname. Classname trong Liệt kê 1 là "MyObject". Các classname giống như các tên bảng trong một cơ sở dữ liệu quan hệ và các đối tượng Parse trong cùng lớp giống như các hàng trong một bảng.

ParseObject trưng ra các phương thức tương tự như các phương thức được cung cấp trong một lớp Map của Java, chẳng hạn như put, getremove, cộng với một số phương thức khác đặc trưng cho ParseObject.

Các khóa tên (name keys) của ParseObject phải là chữ số; theo quy định, sử dụng cách viết hoa chữ cái đầu tiên của các từ cho các khóa tên. Các giá trị có thể là bất kỳ kiểu dữ liệu nào có thể được lưu trữ trong JSON; có nghĩa là, các số, các chuỗi, các kiểu dữ liệu logic, các mảng, JSONObject.NULL, các JSONObject và các JSONArray. Các kiểu dữ liệu khác được ParseObject hỗ trợ là các mảng Datebyte[] của Java. Một ParseObject cũng có thể bao gồm nhiều ParseObject.

Liệt kê 2 cho thấy một số kiểu dữ liệu giá trị của ParseObject được hỗ trợ:

Liệt kê 2. ParseObject: Một số kiểu dữ liệu giá trị được hỗ trợ
// Byte Array
byte[] byteArray = {1, 2, 3, 4, 5};

// A date
Date d = new Date(); // java.util.Date

// A number
int number = 21;

// A String
String name = "Enrique";

// A JSONArray - any mix of JSONObjects, JSONArrays, Strings, Booleans, 
//   Integers, Longs, Doubles, null or NULL.
JSONArray jArray = new JSONArray();
jArray.put(number);
jArray.put(name);

// A JSONObject 
JSONObject jObject = new JSONObject();
try {
    jObject.put("number", number);
    jObject.put("name", name);
} catch (JSONException e) {
    e.printStackTrace();
}

// A ParseObject
ParseObject pObject = new ParseObject("MyObject"); // Class name
pObject.put("myByteArray", byteArray);
pObject.put("myDate", d);
pObject.put("myString", name);
pObject.put("myNumber", number);
pObject.put("myJsonArray", jArray);
pObject.put("myJsonObject", jObject);
pObject.put("myNull", JSONObject.NULL);

Mã trong Liệt kê 2 tạo ra một ParseObject được lưu trữ như một đối tượng trong đám mây Parse. Sau đó nhiều MyObject của cùng lớp được lưu như các hàng của các đối tượng dữ liệu ParseObject để có thể lưu, truy vấn, cập nhật và xóa các đối tượng dữ liệu đó khỏi thiết bị lưu trữ đám mây của Parse. Thậm chí còn có thể lưu dữ liệu khi ứng dụng không nối mạng — thư viện Parse chỉ cần lưu dữ liệu cục bộ cho đến khi một kết nối mạng được thiết lập lại.

Sửa đổi một ParseObject

Nếu bạn đã quen với việc phát triển ứng dụng di động, thì bạn biết rằng các hoạt động lâu dài như các hoạt động mạng nên được chạy ngầm, trên một luồng làm việc (worker thread) và không phải trên luồng giao diện người dùng của hệ thống chính. Điều này sẽ giữ cho luồng của hệ thống chính không chặn và ảnh hưởng đến sự đáp ứng của giao diện người dùng của bạn. Phần sau của bài này, tôi sẽ chỉ cho bạn cách Parse tạo điều kiện thuận lợi cho hoạt động trong nền để lưu, xóa và tìm ra các đối tượng. Bây giờ, hãy xem xét phương thức remove() đồng bộ sau đây được sử dụng để loại bỏ một khóa khỏi đối tượng Parse:

pObject.remove("myNumber"); // remove the field/key "myNumber" from pObject

Sau khi loại bỏ hoặc thêm vào các trường hay cập nhật một trường hiện tại, bạn có thể lưu (hoặc cập nhật) đối tượng dữ liệu trên đám mây bằng cách gọi một trong các phương thức save...() của ParseObject, mà tôi thảo luận sau trong bài này.

Tóm tắt: ParseObject

ParseObject biểu diễn một đối tượng dữ liệu trên đám mây Parse. Nó cung cấp các phương thức để thêm các cặp tên-giá trị, kiểm tra xem một khóa cụ thể đã có mặt chưa và xóa hoặc tìm nạp một ParseObject cụ thể của máy chủ. ParseObject cũng cho phép bạn sử dụng các phương thức get...()put...() khác nhau để xử lý dữ liệu ParseObject, sáp nhập các ParseObject, lưu một ParseObject trong máy chủ và nhiều hơn nữa.

Những người dùng, các vai trò và các ACL của Parse

Trước khi tôi giới thiệu cho bạn cách thực hiện các hoạt động CRUD trên một đối tượng Parse, bạn nên biết một số thông tin về người dùng, các vai trò và các ACL (Danh sách kiểm soát truy cập) của Parse. Tất cả ba điều này đều là các khái niệm và các phương tiện rất quan trọng để bảo vệ các đối tượng dữ liệu ứng dụng của bạn.

Parse users (những người dùng Parse)

Một lớp có tên là ParseUser đại diện cho một người dùng và cung cấp chức năng tài khoản-người dùng cho các ứng dụng Parse. Mỗi ứng dụng Parse có những người dùng Parse liên kết với nó. Một lớp ParseUser là một ParseObject nhưng có các thuộc tính bổ sung là username, password và email. Bạn có thể thêm vào bất kỳ giá trị dữ liệu bổ sung nào mà bạn thấy phù hợp.

Những người dùng ẩn danh trong Parse

Người dùng ẩn danh (anonymous user) trong Parse là người dùng không có username hoặc password. Những người dùng ẩn danh giúp ích cho chức năng không yêu cầu xác thực người dùng của ứng dụng di động. Những người dùng ẩn danh có thể tạo ra các đối tượng dữ liệu, nhưng những đối tượng như vậy chỉ tồn tại trong thời gian rất ngắn và sẽ mất đi khi người dùng ẩn danh thoát khỏi ứng dụng.

Những người dùng có thể đăng ký trở thành Parse users trong ứng dụng của bạn, như trong Liệt kê 3:

Liệt kê 3. ParseUser — đăng ký
ParseUser user = new ParseUser();
user.setUsername("eortiz");
user.setPassword("123456");
user.setEmail("eortiz@nospam.com");
user.put("userType", "Author"); // add another field

// Call the asynchronous background method to sign up 
user.signUpInBackground(new SignUpCallback() {
  public void done(ParseException e) {
    if (e == null) {
      // Successful. Allow access to app.
    } else {
      // Failed....
    }
  }
});

Trường usernameemail phải là duy nhất. Nếu một trường username hoặc email đã được sử dụng rồi, thì cuộc gọi đăng ký sẽ thất bại. Bạn nên có một cơ chế để thông báo cho người dùng biết khi có một trong hai trường thất bại, cũng như một quá trình để thử lại.

Sau khi đăng ký, người dùng có thể đăng nhập vào ứng dụng của bạn, như trong Liệt kê 4:

Liệt kê 4. ParseUser — đăng nhập
ParseUser.logInInBackground("eortiz", "123456", new LogInCallback() {
  public void done(ParseUser user, ParseException e) {
    if (user != null) {
      // Successful. Allow access to app.
    } else {
      // Failed
    }
  }
});

Bạn có thể cập nhật thông tin người dùng bằng cách gọi ParseUser.save(). Tuy nhiên, hãy nhớ rằng chỉ chủ sở hữu của ParseUser mới có thể sửa đổi nội dung của nó; còn những người khác chỉ có thể xem mà không thể chỉnh sửa.

Parse lưu trữ trong bộ nhớ đệm người dùng hiện đã đăng nhập. Bạn có thể truy vấn người dùng hiện tại bằng cách gọi ParseUser.currentUser(). Phương thức currentUser cho phép bạn nhanh chóng truy cập thông tin người dùng hiện tại, do đó bạn chỉ cần nhắc lại các thông tin đăng nhập nếu phiên làm việc của người dùng hiện tại không hoạt động. Liệt kê 5 cho thấy cách lấy ra thông tin người dùng hiện tại trong Parse:

Liệt kê 5. ParseUser — nhận được thông tin người dùng hiện tại
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
  // current user is valid
} else {
  // current user not valid, ask for credentials
}

Thiết lập lại một người dùng hiện tại

Bạn có thể thiết lập lại một người dùng hiện tại trong Parse bằng cách gọi ParseUser.logOut(), như trong Liệt kê 6:

Liệt kê 6. ParseUser — thiết lập lại người dùng hiện tại (đăng xuất)
ParseUser.logOut(); // static method

Các Parse ACL

Một ACL là một danh sách các giấy phép truy cập (hoặc các quyền điều khiển truy cập) gắn liền với một đối tượng dữ liệu. Lớp ParseACL cho phép bạn định nghĩa các giấy phép cho một ParseObject cụ thể. Với các ACL, bạn có thể định nghĩa quyền truy cập công khai vào các đối tượng dữ liệu ứng dụng của mình và bạn có thể hạn chế quyền truy cập cho những người dùng hoặc các nhóm những người dùng (thông qua các vai trò) cụ thể. Liệt kê 7 trình bày việc sử dụng các Parse ACL (ACL của Parse):

Liệt kê 7. Sử dụng lớp ParseACL để có các giấy phép truy cập
// Define a Parse user
ParseUser user = new ParseUser();
user.setUsername(username);
:
:

// Define a read/write ACL
ParseACL rwACL = new ParseACL();
rwACL.setReadAccess(user, true); // allow user to do reads
rwACL.setWriteAccess(user, true); // allow user to do writes
:
:

// Define a Parse object and its ACL
ParseObject gameObject = new ParseObject("Game");
gameObject.setACL(rwACL); // allow user do read/writes on gameObject
gameObject.saveInBackground(); // save the ACL'ed object to the cloud
:
:

// You can define a public ACL that gives public access to the object
ParseACL publicACL = new ParseACL();
publicACL.setPublicReadAccess(true);
publicACL.setPublicWriteAccess(true);      
gameObject.setACL(publicACL); // allow public read/writes
gameObject.saveInBackground(); // save the ACL'ed object to the cloud

Bạn cũng có thể định nghĩa một ACL mặc định cho tất cả các đối tượng mới được tạo ra. Trong Liệt kê 8 tôi đã thiết lập ACL mặc định là công khai cho các lần đọc và viết, như publicACL đã định nghĩa trong Liệt kê 7.

Liệt kê 8. Thiết lập ACL mặc định
// Set a default ACL for all newly created objects as public access
ParseACL.setDefaultACL(publicACL, true);

Mặc dù không trình bày ở đây, nhưng chúng ta vẫn có thể sử dụng lớp ParseRole để cấp các giấy phép truy cập cho các nhóm những người dùng.

Tiếp theo, chúng ta sẽ xem xét cách lưu và lấy ra các đối tượng dữ liệu Parse từ Parse cloud.

Các đối tượng dữ liệu Parse trên đám mây

Một khi bạn đã tạo ra và điền vào một ParseObject, bạn có thể lưu nó trên Parse cloud. Việc lưu các đối tượng dữ liệu trên Parse cloud thực sự là một trong những điều đơn giản nhất để làm với Parse; Parse hoàn toàn che giấu đi sự phức tạp thường liên quan đến việc biểu diễn dữ liệu, sắp xếp dữ liệu (marshaling), truyền thông mạng và vận chuyển và v.v. Bạn sẽ cần sử dụng các phương thức của trình trợ giúp để ánh xạ cá thể đối tượng dữ liệu của mình vào một ParseObject và ngược lại và bạn sẽ cần quyết định xem bạn có muốn gửi hoạt động lưu trữ của Parse trên luồng riêng của mình không hoặc có sử dụng lưu trữ theo phương thức nền không.

Hãy coi chừng chặn luồng hệ thống!

Hãy nhớ lại rằng trong các ứng dụng di động, không nên thực hiện các hoạt động kéo dài như hoạt động mạng, hoạt động tệp hoặc các tính toán dài dòng trên luồng hệ thống chính. Thay vào đó, hãy thực hiện các hoạt động đó trong một luồng công việc riêng biệt. Việc chặn luồng hệ thống sẽ ảnh hưởng tiêu cực đến đáp ứng giao diện người dùng của ứng dụng, có khả năng dẫn đến ứng dụng của bạn bị buộc phải đóng lại.

ParseObject cung cấp hai loại trong số các phương thức lưu trữ: save()saveInBackground(). saveInBackground() (lưu trữ trong nền) là phương thức lưu trữ nên dùng do nó chạy hoạt động lưu trữ trên luồng công việc riêng của nó. Nếu bạn chọn sử dụng phương thức save() (lưu) đồng bộ, hãy hiểu rõ rằng việc gọi phương thức này trên luồng công việc của riêng nó để ngăn giao diện người dùng không chặn luồng hệ thống là trách nhiệm của bạn.

Liệt kê 9 cho thấy mã để lưu một đối tượng dữ liệu Parse trong nền:

Liệt kê 9. Lưu ParseObject trong nền
// ParseObject
ParseObject pObject = new ParseObject("ExampleObject");
pObject.put("myNumber", number);
pObject.put("myString", name);
pObject.saveInBackground(); // asynchronous, no callback

Còn Liệt kê 10 cho thấy mã dùng để lưu một đối tượng dữ liệu Parse trong nền với một cuộc gọi lại:

Liệt kê 10. Lưu trong nền với cuộc gọi lại
pObject.saveInBackground(new SaveCallback () {
    @Override
    public void done(ParseException ex) {
        if (ex == null) {
            isSaved = true;
        } else {
            // Failed
            isSaved = false;
        }
    }
  });

Các biến thể của phương thức save...() bao gồm:

  • saveAllinBackground() lưu một ParseObject có hoặc không có một cuộc gọi lại.
  • saveAll(List<ParseObject> objects) lưu một danh sách các ParseObject.
  • saveAllinBackground(List<ParseObject> objects) lưu một danh sách các ParseObject trong nền.
  • saveEventually() cho phép bạn lưu một đối tượng dữ liệu vào máy chủ tại một thời điểm nào đó trong tương lai; sử dụng phương thức này nếu Parse cloud hiện tại không thể truy cập được.

Khi một ParseObject đã được lưu thành công trên Đám mây, nó được gán cho một mã định danh đối tượng (Object-ID) duy nhất. Object-ID này là rất quan trọng vì chỉ có nó mới nhận ra được cá thể ParseObject đó. Bạn sẽ sử dụng Object-ID, ví dụ, để xác định xem đối tượng đã được lưu thành công trên đám mây chưa, để lấy ra và làm mới một cá thể đối tượng Parse đã cho và để xóa một ParseObject cụ thể.

Lấy ra các đối tượng dữ liệu từ đám mây

Phần này xem xét các phương thức để truy vấn và lấy ra các đối tượng dữ liệu đã lưu trên Parse cloud. Bạn có thể truy vấn một ParseObject đơn lẻ theo object-ID hoặc bạn có thể truy vấn một hoặc nhiều đối tượng Parse bằng cách sử dụng các thuộc tính. Nếu bạn đã có một ParseObject rồi, bạn có thể làm mới hoặc đồng bộ hóa các nội dung của nó bằng cách tìm nạp các giá trị mới nhất từ máy chủ. Chúng tôi sẽ xem xét tất cả các tùy chọn này trong các đoạn mã sau đây.

Tìm nạp các ParseObject

Để tìm nạp một đối tượng dữ liệu từ đám mây Parse, hãy sử dụng phương thức của ParseObjectfetch() (tìm nạp) hoặc fetchInBackground() (tìm nạp trong nền), được hiển thị trong Liệt kê 11:

Liệt kê 11. Tìm nạp (vô điều kiện)
// ParseObject
ParseObject pObject = new ParseObject("ExampleObject");
:
:

// Fetch the parse object unconditionally
try {
    pObject.fetch();
} catch (ParseException e) {
    e.printStackTrace();
}

// Fetch the parse object unconditionally, with Callback
pObject.fetchInBackground(new GetCallback() {
    @Override
    public void done(ParseObject obj, ParseException ex) {
        if (ex == null) {
            // Success
        } else {
            // Failed
        }            
    }
});

Bạn cũng có thể tìm nạp chỉ khi cần; ví dụ, khi tìm nạp một đối tượng Parse có các đối tượng Parse liên quan, như trong Liệt kê 12:

Liệt kê 12. Tìm nạp khi cần
ParseObject po = new ParseObject("ExampleObject");
:

ParseObject po2 = po.getParseObject("key");

// Fetch only if needed
try {
    po2.fetchIfNeeded();
} catch (ParseException e) {
    e.printStackTrace();
}

Một lựa chọn khác là thực hiện một hoạt động tìm nạp nếu cần trong nền và với một cuộc gọi lại. Về việc này, bạn nên sử dụng phương thức đối tượng Parse là fetchIfNeededInBackground(GetCallback callback).

Trong một số trường hợp, bạn sẽ cần tìm nạp một bộ sưu tập của các đối tượng Parse cùng một lúc, vô điều kiện hoặc chỉ khi cần. ParseObject cung cấp một tập hợp các phương thức tĩnh để làm việc này; mỗi phương thức tĩnh nhận đầu vào là một danh sách các đối tượng Parse và sau đó trả về một danh sách các đối tượng Parse:

  • fetchAll(List<ParseObject> objects)
  • fetchAllIfNeeded(List<ParseObject> objects)
  • fetchAllIfNeededInBackground(List<ParseObject> objects, FindCallback callback)
  • fetchAllInBackground(List<ParseObject> objects, FindCallback callback)

Truy vấn các đối tượng dữ liệu trên đám mây

Giờ đây, hy vọng bạn đã thấy rằng Parse API rất toàn diện — nhưng hãy chờ xem, bởi vì còn có nhiều điều hay ho hơn nữa! Ngoài việc tìm nạp các đối tượng dữ liệu, Parse cũng cho phép bạn truy vấn các đối tượng dữ liệu bằng cách sử dụng object-ID hoặc các thuộc tính. Để truy vấn một đối tượng dữ liệu từ đám mây Parse, hãy sử dụng lớp ParseQuery. Bạn có thể sử dụng lớp ParseQuery cho cả hai các truy vấn dữ liệu cơ bản và các truy vấn dữ liệu phức tạp, thu nhận lại một đối tượng đã cho hoặc một List (Danh sách) các đối tượng phù hợp.

Liệt kê 13 cho thấy cách lấy ra một đối tượng Parse cụ thể từ máy chủ trong một luồng nền, dựa vào một object-ID:

Liệt kê 13. Sử dụng lớp ParseQuery để lấy ra một ParseObject đã cho
String myID = "12345";
ParseQuery query = new ParseQuery("Players");
query.getInBackground(myID, new GetCallback() {
    @Override
    public void done(ParseObject object, ParseException e) {
        if (object != null) {
            // Get object
        } else {
            // Not found
        }
    }            
});

Lưu ý query.getInBackground() không sử dụng bộ nhớ đệm ParseQuery.

Liệt kê 14 cho thấy một truy vấn để lấy ra tất cả các đối tượng dữ liệu của lớp: Players. (Không cung cấp sự ràng buộc nào).

Liệt kê 14. Sử dụng lớp ParseQuery cho tất cả các ParseObject của một lớp đã cho
ParseQuery query = new ParseQuery("Players");
query.findInBackground(new FindCallback() {
    @Override
    public void done(List<ParseObject> players, ParseException e) {
        if (players != null) {
            // Get list of players
        } else {
            // No players
        }
    }
});

ITrong Liệt kê 15, tôi đã sử dụng một sự ràng buộc truy vấn để lấy ra một hoặc nhiều đối tượng Parse phù hợp; trong trường hợp này ParseObject là Players đang hoạt động (active):

Liệt kê 15. Sử dụng lớp ParseQuery để lấy ra các ParseObject phù hợp
ParseQuery query = new ParseQuery("Players");
query.whereEqualTo("status", "active");
query.findInBackground(new FindCallback() {
    @Override
    public void done(List<ParseObject> players, ParseException e) {
        if (players != null) {
            // Success - players contain active players 
        } else {
            // Failed
        }
    }
});

Lớp ParseQuery cũng cung cấp một phương thức để nhận được tổng số đếm của các đối tượng phù hợp mà không cần lấy ra chính các đối tượng đó, điều này rất có ích. Liệt kê 16 cho thấy cách nhận được tổng số đếm của players đang hoạt động:

Liệt kê 16. Sử dụng lớp ParseQuery để đếm các ParseObject phù hợp
ParseQuery query = new ParseQuery("Players");
query.whereEqualTo("status", "active"); //remove this line to count ALL
query.countInBackground(new CountCallback() {
    @Override
    public void done(int count, ParseException e) {
        if (e == null) {
            // Success, see count variable
        } else {
            // Failed
        }
    }
});

Các phương thức và các ràng buộc của lớp ParseQuery

Lớp ParseQuery hỗ trợ hơn 20 phương thức ràng buộc-truy vấn khác nhau; dưới đây là một số ví dụ:

  • whereMatches(String key, String regex) tìm các giá trị chuỗi phù hợp với biểu thức chính quy được cung cấp.
  • whereStartsWith(String key, String prefix) tìm các giá trị chuỗi bắt đầu với một chuỗi được cung cấp.
  • whereContains(String key, String substring) tìm các giá trị có chứa một chuỗi được cung cấp.
  • whereGreaterThan(String key, Object value) tìm các giá trị lớn hơn giá trị được cung cấp.
  • whereWithinKilometers(String key, ParseGeoPoint point, double maxDistance) tìm các đối tượng có các giá trị điểm gần điểm đã cho và trong khoảng cách tối đa đã cho.

Các kết quả truy vấn có thể được sắp xếp thứ tự, như thể hiện trong Liệt kê 17. Để sắp xếp thứ tự các kết quả truy vấn, hãy gọi một trong các phương thức query orderBy...(), chỉ rõ các trường sắp xếp theo thứ tự.

Liệt kê 17. Sắp xếp thứ tự các kết quả truy vấn
query.orderByAscending("name"); 

query.orderByDescending("name");



For example:



ParseQuery query = new ParseQuery("Players");
query.whereEqualTo("status", "active");
query.orderByAscending("lastName"); // By lastname ascending order
query.findInBackground(new FindCallback() {
    @Override

  public void done(List<ParseObject> players, ParseException e) {

    if (players != null) {
      // Success - players contain active players

    } else {

      // Failed
		
                          } 

             }	

});

Một số thứ khác cần lưu ý là các kết quả của lớp ParseQuery được lưu trữ trong bộ nhớ đệm. Bạn có thể thiết lập chính sách truy vấn-bộ nhớ đệm (query-cache) theo nhiều cách khác nhau tùy thuộc vào các nhu cầu ứng dụng của mình. Các chính sách bộ nhớ đệm sau đây hiện đang được hỗ trợ:

  • IGNORE_CACHE: Không sử dụng bộ nhớ đệm; đây là chính sách bộ nhớ đệm mặc định.
  • CACHE_ONLY: Nếu không có kết quả nào được lưu trong bộ nhớ đệm, thì sẽ có một ParseException (Trường hợp Parse ngoại lệ).
  • NETWORK_ONLY: Luôn vào mạng, nhưng lưu các kết quả vào bộ nhớ đệm.
  • CACHE_ELSE_NETWORK: Trước tiên truy cập bộ nhớ đệm. Nếu thất bại, hãy tải từ mạng. Nếu không thể truy cập thành công vào cả bộ nhớ đệm lẫn mạng, kết quả sẽ là một ParseException.
  • NETWORK_ELSE_CACHE: Trước hết truy cập mạng. Nếu thất bại, hãy tải từ bộ nhớ đệm. Nếu không thể truy cập thành công vào cả mạng lẫn bộ nhớ đệm, kết quả sẽ là một ParseException.
  • CACHE_THEN_NETWORK: Trước tiên truy cập bộ nhớ đệm, sau đó tải từ mạng. Lưu ý rằng FindCallback sẽ thực sự được gọi hai lần: lần đầu tiên với các kết quả đã lưu trong bộ nhớ đệm, sau đó với các kết quả trên mạng. Chính sách này chỉ có thể được sử dụng không đồng bộ với findInBackground.

Việc thiết lập chính sách bộ nhớ đệm đơn giản. Hãy thiết lập nó trước khi gọi phương thức find...(), như trong Liệt kê 18:

Liệt kê 18. Quản lý CachePolicy
ParseQuery query = new ParseQuery("Players");
query.setCachePolicy(ParseQuery.CachePolicy.NETWORK_ELSE_CACHE);
query.findInBackground(new FindCallback() {
    @Override
    public void done(List<ParseObject> players, ParseException e) {
        if (e == null) {
            // Success - players contain active players 
        } else {
            // Failed
        }
    }
});

Lớp ParseQuery cung cấp tất cả các phương thức cần thiết để truy vấn các đối tượng dữ liệu đã lưu trên đám mây. Với lớp ParseQuery, bạn có thể chỉ rõ các ràng buộc truy vấn của tất cả các loại, đếm các đối tượng dữ liệu phù hợp, thiết lập các hạn chế, bỏ qua các đối tượng dữ liệu, sắp xếp theo thứ tự, làm sạch bộ nhớ đệm và nhiều hơn nữa.


Loại bỏ các đối tượng dữ liệu

Việc loại bỏ một đối tượng dữ liệu từ Parse cloud cũng rất đơn giản. Một khi bạn có cá thể đối tượng, bạn có thể xóa một ParseObject hiện có khỏi đám mây bằng cách gọi phương thức của ParseObjectdelete() hoặc deleteInBackground() (Xóa trong nền). Cả hai phương thức đều được thể hiện trong Liệt kê 19:

Liệt kê 19. Loại bỏ một đối tượng Parse khỏi đám mây
parseObject.delete();
parseObject.deleteInBackground();

Như bạn có thể đoán trước được, phương thức, delete() là một lời gọi chặn, có nghĩa là để gửi đi lời gọi này trên luồng công việc riêng của nó là trách nhiệm của bạn. Hoặc bạn có thể để cho Parse chịu trách nhiệm tạo luồng bằng cách sử dụng phương thức deleteInBackground() có hoặc không có một cuộc gọi lại.

Làm việc với các tệp files

Đến thời điểm này, chúng ta đã làm việc với các đối tượng Parse và các truy vấn Parse. Tôi cũng đã giới thiệu cho bạn về những users, các ACL và các vai trò của Parse. Tôi sẽ kết thúc bằng một trình bày về làm việc với các chức năng đọc, viết và lưu tệp trong Parse.

Hãy nhớ lại rằng bạn có thể lưu trữ dữ liệu byte [] thô trong một ParseObject, việc này rất tốt với lượng nhỏ dữ liệu. Khi lưu trữ các mục lớn hơn chẳng hạn như các hình ảnh hoặc các tài liệu, hãy sử dụng Parse Files (Các tệp Parse).

Các tệp trong Parse cloud được biểu diễn bằng cách sử dụng ParseFile nhằm cung cấp các phương thức để có được tên của một tệp, URL của nó và bản thân dữ liệu tệp, giả sử tệp đó có sẵn. Bạn cũng có thể tải về và tải lên các tệp và truy cập một số phương thức của trình trợ giúp khác.

Dữ liệu tệp được biểu diễn bằng cú pháp byte[]. Lưu ý rằng hiện nay, một tệp cụ thể không thể lớn hơn 10MB. Khi đặt tên một tệp, thư viện Parse chịu trách nhiệm về các xung đột tên tiềm ẩn. Việc cung cấp một phần mở rộng của tệp giúp Parse xử lý nội dung tệp.

Liệt kê 20 trình bày cách lưu một tệp JPG:

Liệt kê 20. Lưu một ParseFile
// Save image file
Drawable drawable = ...;
Bitmap bitmap = (Bitmap)((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] data = stream.toByteArray();                
ParseFile imageFile = new ParseFile("image.jpg", data);
imageFile.saveInBackground();

Các câu lệnh đầu tiên trong Liệt kê 20 chuyển đổi bitmap thành một byte[]. Sau đó byte[] sẽ được lưu bằng cách sử dụng một phương thức ParseFile saveInBackground(), tương tự như cách lưu một ParseObject trên máy chủ.

Một khi tệp đã được lưu trên Parse, nó phải được liên kết (đưa vào) với một ParseOject. Nói cách khác, các tệp Parse không thực sự là các đối tượng độc lập và để lấy ra và sử dụng tệp sau này, nó phải được liên kết với một cá thể ParseObject đã cho. Có thể giải quyết sự hạn chế này trong một bản phát hành tương lai của Parse. Liệt kê 21 liên kết tệp hình ảnh với một đối tượng Parse là Player:

Liệt kê 21. Liên kết một ParseFile với một ParseObject
// Associate image with Parse object
ParseObject po = new ParseObject("Players");
po.put("name", "eortiz");
po.put("photo", imageFile);
po.saveInBackground();

Tôi đã liên kết tệp này với đối tượng dữ liệu, sau đó lưu đối tượng đó lên máy chủ bằng cách sử dụng phương thức saveInBackgroud(). Điều này đã được thảo luận ở trên.

Liệt kê 22 cho thấy cách lấy ra một tệp được liên kết với một đối tượng dữ liệu:

Liệt kê 22. Lấy ra ParseFile
// Retrieving the file 
ParseFile imageFile2 = (ParseFile)po.get("photo");
imageFile2.getDataInBackground(new GetDataCallback() {
  public void done(byte[] data, ParseException e) {
    if (data != null) {
      // Success; data has the file
    } else {
      // Failed
    }
  }
});

Sau khi nhận được một tài liệu tham khảo ParseFile từ đối tượng Parse, tôi đã gọi getDataInBackground() để lấy ra ParseFile từ các máy chủ. Lưu ý rằng tôi đã sử dụng lời gọi GetDataCallback để lấy ra các tệp Parse, khác với GetCallback là để lấy ra các đối tượng Parse với lớp ParseQuery.

Kết luận

Parse API là rất toàn diện và bao gồm các lớp để truy cập dịch vụ di động chẳng hạn như tin nhắn push, sử dụng dữ liệu địa lý, kết hợp với các nền tảng truyền thông xã hội và nhiều hơn nữa. Trong bài này, tôi đã xem xét sơ bộ về những gì bạn có thể làm với Parse bằng cách giới thiệu các Parse API để lưu trữ trên đám mây dữ liệu và tệp. Việc biết cách lưu trữ và xử lý những người dùng, các đối tượng dữ liệu, các tệp và các ACL của Parse trong đám mây Parse là nền tảng tốt để tiếp tục khám phá nền tảng đám mây này cho việc phát triển di động.

Lời cảm ơn

Rất cám ơn Athen O'Shea vì đã xem lại bài viết này.

Tài nguyên

Học tập

  • Tìm hiểu thêm về SDK Android của Parse ; ngoài ra hãy xem Hướng dẫn nhanh về Parse để chọn một nền tảng di động, thiết lập một ứng dụng và tải về và cài đặt SDK của Parse.
  • Xem danh sách đầy đủ về các API Android của Parse.
  • "Phát triển các ứng dụng Android với Eclipse (Frank Ableson, developerWorks, 02.2008): Thực hành nhiều hơn bằng cách phát triển các ứng dụng Android trong môi trường phát triển Eclipse, hiện đang sử dụng trình cắm thêm Eclipse Android.
  • "Giới thiệu về jQuery Mobile" (C. Enrique Ortiz, developerWorks, 05.2012): Tìm hiểu những điều cơ bản về jQuery Mobile và cách viết một giao diện người dùng của ứng dụng web có chức năng di động. Các ví dụ đang làm việc sẽ hướng dẫn bạn thông qua các trang, chuyển hướng, các thanh công cụ, các khung nhìn danh sách, kiểm soát dạng mẫu và các hiệu ứng chuyển tiếp trong jQuery Mobile.
  • "Giải quyết các thách thức tích hợp ứng dụng di động nhiều thiết bị cho nhiều nền tảng của bạn" (Olivier Picciotto, developerWorks, 08.2012): Sự phát triển di động và điện toán đám mây hầu như không thể tách rời những ngày này, nhưng tích hợp các ứng dụng di động vào đám mây vẫn còn là lĩnh vực mới mẻ. Hãy tìm hiểu xem nền tảng ứng dụng di động cho doanh nghiệp (MEAP) giải quyết một số thách thức tích hợp di động-lên-đám mây ra sao.
  • "DevOps dùng để phát triển di động" (Michael Rowe, developerWorks, 07.2012): Tất cả các công ty trên toàn thế giới đều muốn khai thác thị trường di động bằng cách cung cấp cho các khách hàng và người dùng các ứng dụng để làm cho điện toán di động dễ dàng hơn. Bài viết này suy nghĩ về một số vấn đề kỹ thuật và nghiệp vụ có liên quan đến việc tích hợp phát triển và các hoạt động cho các nền tảng di động tại nơi làm việc.
  • Theo dõi developerWorks trên Twitter.
  • Xem các trình diễn theo yêu cầu trên developerWorks trải rộng từ các trình diễn cài đặt sản phẩm và thiết lập dành cho người mới bắt đầu đến các chức năng nâng cao cho các nhà phát triển có kinh nghiệm.

Thảo luận

  • Hãy tham gia vào cộng đồng developerWorks. Kết nối với những người dùng developerWorks khác trong khi khám phá các blog, các diễn đàn, các nhóm và các wiki theo hướng nhà phát triển.

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Công nghệ Java, Cloud computing
ArticleID=928689
ArticleTitle=Các dịch vụ đám mây của Parse dành cho Android
publish-date=05032013