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.

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.

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

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

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, get và remove, 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 Date và

byte[] 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.

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 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 username và email 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() và

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 objects) lưu một danh sách các ParseObject.

 saveAllinBackground(List 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

ParseObject là fetch() (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 objects)

fetchAllIfNeeded(List objects)

fetchAllIfNeededInBackground(List objects, FindCallback

callback)

fetchAllInBackground(List 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 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 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 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 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 ParseObject là delete() 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.