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.

pdf34 trang | Chia sẻ: lylyngoc | Lượt xem: 1660 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Các dịch vụ đám mây của Parse dành cho Android, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
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"); qu