AVOS Cloud 移动开发 SDK 为 iOS、Android 和 WindowsPhone® 应用程序提供了基于云的 API 和服务,而且还提供了 JavaScript 和 REST API。使用 AVOS Cloud API,您能够极快地以最少工做量让您的移动应用程序支持云处理。集成了 AVOS Cloud SDK 的移动应用程序能够轻松地在 AVOS Cloud 云上存储数据对象和文件,发送并侦听推送通知,管理用户,处理地理位置数据,并能够轻松得到移动 IM 的能力。html
开始以前
出于本文的目的,我假设您已经很是熟悉使用 JSON、Android 和 Eclipse 进行移动应用编程的基本概念。在您继续阅读本文以前,请访问 avoscloud.com 并建立您的应用程序。只需遵循注册页面中的简单指令便可。java
本文介绍了包含用户、数据对象和文件的核心 API 类。您将学习如何使用访问控制列表 (ACL),以及如何在数据对象上执行 CRUD 操做,还有如何在 AVOS Cloud 云端存储和检索文件。示例均构建于 AVOS Cloud SDK for Android 之上(请参阅Android开发指南)。android
AVOS Cloud 控制台能够帮助开发人员管理应用程序。该控制台为 API、文件和推送的通知提供了通常指标和应用程序特定的使用指标。经过控制台可管理应用程序的基本设置信息,它还提供了数据浏览器,使开发人员可以浏览(甚至编辑)所存储的数据对象。数据浏览器对于调试很是有用。图 1 是 AVOS Cloud 控制台的屏幕截图:正则表达式
经过一个 App ID 和 App Key 对应用程序进行身份验证。为了得到您的应用程序 ID 和 Key,必须经过 AVOS Cloud 控制台注册您的应用程序。在您的应用程序上初始化 AVOS Cloud SDK 时,会用到这些信息。数据库
在 AVOS Cloud 中,使用 “键-值” 对的容器 AVObject 表示数据。AVObject 能够存储任何与 JSON 兼容的数据,如清单 1 所示:编程
AVObject myObject = new AVObject("MyObject"); // Class Namemy Object.put("name", “Feng Junwen"); myObject.put("twitterHandle", “jwfing"); myObject.put("followers", 123456);
AVObject 在实例化时被赋予一个 classname(类名称)。在上述代码中,类名称是 "MyObject"。类名称与关系数据库中的表名称类似,同一类的 AVObject 对象至关于表中的行。segmentfault
AVObject 暴露的方法相似于 Java Map 类中的方法,如 put、get 和 remove,以及大量特定于 AVObject 的其余方法。数组
AVObject名称键 必须是字母数字的,做为一个指导方针,请对名称键使用驼峰式大小写 (camel-casing) 格式。值能够是存储在 JSON 中的任何数据类型,也就是说,能够是数字、字符串、布尔值、数组、JSONObject.NULL、JSONObject 和 JSONArray。AVObject 所支持的其余数据类型是 Java Date 和 byte[] 数组。AVObject 还能够嵌套包含其余 AVObject。浏览器
清单 2 显示了部分受支持的 AVObject 值数据类型:缓存
// 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 AVObject AVObject pObject = new AVObject("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);
上述代码建立了一个 AVObject,它在 AVOS Cloud 云端被存储为一个对象。以后,咱们能够保存、查询和更新,并能从云端存储中删除。甚至能够在应用程序离线时保存数据,AVOS Cloud SDK 将数据保存在本地,直到从新创建网络链接。
若是您熟悉移动应用程序开发,那么您就会知道,网络操做等长时间操做通常都是在后台完成,或在一个工做线程上完成,而不是在主系统的 UI 线程上完成。这样能够避免主线程发生阻塞并影响用户界面的响应速度。稍后,在本文的后半部分,我会告诉您 AVOS Cloud 如何为后台工做提供便利,从而保存、删除和查找对象。如今,考虑下面的同步 remove() 方法,可使用它从 AVObject 删除一个字段:
pObject.remove("myNumber"); // remove the field/key "myNumber" from pObject
在删除或添加字段后,或在更新当前字段后,您能够在云端保存(或更新)数据对象,只需调用其中一个 AVObject 的 save...() 方法,我稍后会在本文中讨论它们。
在我告诉您如何在 AVOS Cloud 对象上执行 CRUD 操做以前,您应该了解一下 用户、角色和 ACL(访问控制列表)。这三个都是很是重要的概念,有助于保护您的应用程序的数据对象。
名称为 AVUser 的类表明一个用户,并为应用程序提供账户管理功能。每一个应用程序都有与之关联的 AVUser 表。一个 AVUser 也是一个 AVObject,但具备更多的属性,如用户名、密码和电子邮件。您能够添加任何您认为合适的其余数据值。
AVOS Cloud 中的匿名用户
在 AVOS Cloud 中,匿名用户是没有用户名或密码的用户。匿名用户对于那些不要求用户身份验证的移动应用程序功能很是有用。匿名用户能够建立数据对象,但这些对象寿命很短,而且在匿名用户登出以后就再也不可用。
用户能够注册成为您应用的 AVUser 用户,如清单 3 (AVUser — 注册)所示:
AVUser user = new AVUser(); user.setUsername(“Feng Junwen"); user.setPassword(“123456&asdQWE"); user.setEmail(“jfeng@avoscloud.com"); user.put("userType", "Author"); // add another field // Call the asynchronous background method to sign up user.signUpInBackground(new SignUpCallback() { public void done(AVException e) { if (e == null) { // Successful. Allow access to app. } else { // Failed.... } } });
username 和 email 必须是应用内唯一的。若是 username 或 email 已经被使用,那么注册调用将会失败。您应该有一个通知用户字段限制的机制,并提供一个重试的进程。
在注册以后,用户就能够登陆您的应用,如清单 4 (AVUser — 登陆)所示:
AVUser.logInInBackground(“Feng Junwen", “123456&asdQWE", new LogInCallback() { public void done(AVUser user, AVException e) { if (user != null) { // Successful. Allow access to app. } else { // Failed } } });
您能够经过调用 AVUser.save() 更新用户信息。 可是请注意,只有 AVUser 的全部者能够修改其内容,数据对于其余任何人都是只读的。
AVOS Cloud SDK 会缓存当前登陆的用户。您能够经过调用 AVUser.currentUser() 查询当前用户。currentUser 方法使您可以快速访问当前用户信息,那么若是当前用户会话没有激活,您只须要根据提示输入验证。清单 5 (AVUser — 得到当前用户)显示了如何获取当前用户:
AVUser currentUser = AVUser.getCurrentUser(); if (currentUser != null) { // current user is valid } else { // current user not valid, ask for credentials }
在 AVOS Cloud 中,您能够经过调用 AVUser.logOut() 来重置当前用户,如清单 6(AVUser — 重置当前用户) 所示:
AVUser.logOut(); // static method
ACL 是关联到数据对象的访问权限(或控制)列表。AVACL 类容许您为给定的 AVObject 定义权限。使用 ACL,您能够定义对您的应用程序数据对象的公共访问,而且能够(经过角色)限制对特定用户或用户组的访问。清单 7 演示了 AVOS Cloud ACL 的用法:
// Define a AVOS Cloud user AVUser user = new AVUser(); user.setUsername(username); : : // Define a read/write ACL AVACL rwACL = new AVACL(); rwACL.setReadAccess(user, true); // allow user to do reads rwACL.setWriteAccess(user, true); // allow user to do writes : : // Define a AVOS Cloud object and its ACL AVObject gameObject = new AVObject("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 AVACL publicACL = new AVACL(); publicACL.setPublicReadAccess(true); publicACL.setPublicWriteAccess(true); gameObject.setACL(publicACL); // allow public read/writes gameObject.saveInBackground(); // save the ACL'ed object to the cloud
您还能够为全部新建立的对象定义一个默认的 ACL。在清单 8 中,我已经将可读取和写入的默认 ACL 设置为 public,清单 7 中的 publicACL定义。
清单 8. 设置默认的 ACL
// Set a default ACL for all newly created objects as public access AVACL.setDefaultACL(publicACL, true);
虽然在这里没有演示,但咱们也可使用 AVRole 类为用户组授予访问权限。接下来,咱们将查看如何将 AVObject 数据对象保存到 AVOS Cloud 云,并在云端检索它们。
一旦建立并填充了 AVObject,就能够在 AVOS Cloud 云上保存。在云端保存数据对象其实是利用 AVOS Cloud 最简单的操做之一,其复杂性一般与数据表示、编组、网络通讯和传输等有关联,AVOS Cloud SDK 彻底隐藏了此复杂性。您须要使用 helper 方法来将数据对象实例映射到 AVObject,并映射回来,您须要决定是在您本身的线程上调度 AVOS Cloud 保存操做,仍是使用 save-in-the-background 方法。
谨防系统线程阻塞!
回想一下,在移动应用程序中,长时间的操做(如网络、文件或长的计算)不该该在主系统线程上完成。相反,应在一个单独的工做线程中执行它们。阻塞系统线程会对应用程序的用户界面的响应能力产生负面影响,有可能致使强行关闭您的应用程序。
AVObject 提供两个保存方法: save() 和 saveInBackground()。 saveInBackground()是建议的保存方法,由于它在本身的工做线程上运行保存操做。若是您选择使用同步的save() 方法,须要注意的是,您须要在该方法本身的工做线程上调用该方法,以免 UI 被阻塞。
清单 9 (在后台保存 AVObject)显示的代码在后台保存 AVObject 数据对象:
AVObject pObject = new AVObject("ExampleObject"); pObject.put("myNumber", number); pObject.put("myString", name); pObject.saveInBackground(); // asynchronous, no callback
清单 10(使用回调,在后台保存) 显示的代码使用了一个回调,在后台保存 AVObject 数据对象:
pObject.saveInBackground(new SaveCallback () { @Override public void done(AVException ex) { if (ex == null) { isSaved = true; } else { // Failed isSaved = false; } } });
save...() 方法的变形包括如下几种:
一旦在云上已成功保存了 AVObject ,就会为对象提供唯一的 Object-ID。此 Object-ID 很是重要,由于它唯一地标识了此 AVObject 实例。例如,您可使用 Object-ID 肯定是否已在云上成功保存该对象,以便检索或刷新给定的对象实例和删除特定的 AVObject。
这一节将探讨查询和检索 AVOS Cloud 云上的数据对象的方法。您能够经过 object-ID 查询一个 AVObject,您也可使用属性查询一个或多个 AVObject 对象。若是您已经有一个 AVObject,那么您能够经过从服务器提取最新的值,刷新或同步其内容。咱们将在如下代码片断中探讨全部这些选项。
为了从 AVOS Cloud 云提取数据对象,使用 AVObject 方法 fetch() 或 fetchInBackground(),如清单 11(提取) 所示:
AVObject pObject = new AVObject("ExampleObject"); : : // Fetch the AVOS Cloud object unconditionally try { pObject.fetch(); } catch (AVException e) { e.printStackTrace(); } // Fetch the AVOS Cloud object unconditionally, with Callback pObject.fetchInBackground(new GetCallback() { @Override public void done(AVObject obj, AVException ex) { if (ex == null) { // Success } else { // Failed } } });
您也能够仅在须要时提取数据,例如,提取一个 AVOS Cloud 对象关联的 AVObject 对象,如清单 12(根据须要进行提取):
AVObject po = new AVObject("ExampleObject"); : AVObject po2 = po.getAVObject("key"); // Fetch only if needed try { po2.fetchIfNeeded(); } catch (AVException e) { e.printStackTrace(); }
另外一个选项是在后台根据须要执行提取操做,并使用一个回调。为此,可使用 AVObject 的 fetchIfNeededInBackground(GetCallback callback) 方法。
在某些状况下,您须要无条件地或仅在须要时一次提取一个 AVObject 集合。AVObject 为此提供了一组静态方法,每一个方法都将一个 AVObject 的列表做为输入,而后返回一个 AVObject 的列表:
但愿您如今已看到 AVOS Cloud API 的强大,可是别着急,它还有更多功能!除了提取数据对象以外,AVOS Cloud 还可让您使用 object-ID 或属性来查询数据对象。要从云端查询一个数据对象,可使用 AVQuery。您可使用 AVQuery 进行基本的和复杂的数据查询,接收给定的对象或匹配对象的 List。
清单 13(使用 AVQuery 检索给定的 AVObject) 显示了如何在一个后台线程中使用给定 object-ID 从服务器检索特定的 AVObject:
String myID = "12345"; AVQuery query = new AVQuery("Players"); query.getInBackground(myID, new GetCallback() { @Override public void done(AVObject object, AVException e) { if (object != null) { // Get object } else { // Not found } } });
请注意,query.getInBackground() 没有使用 AVQuery 缓存。
清单 14(对给定类的全部 AVObjects 使用 AVQuery) 显示的查询检索 Players 类的全部数据对象。(没有提供约束。)
AVQuery query = new AVQuery("Players"); query.findInBackground(new FindCallback() { @Override public void done(List<AVObject> players, AVException e) { if (players != null) { // Get list of players } else { // No players } } });
在清单 15(使用 AVQuery 检索匹配的 AVObjects) 中,我使用了一个查询约束来检索一个或多个匹配的 AVObject;在本例中,但愿找到全部活跃的 Players:
AVQuery query = new AVQuery("Players"); query.whereEqualTo("status", "active"); query.findInBackground(new FindCallback() { @Override public void done(List<AVObject> players, AVException e) { if (players != null) { // Success - players contain active players } else { // Failed } } });
AVQuery 还提供了一个方法来得到匹配对象的计数,不须要检索对象自己,这很是有用。清单 16(使用 AVQuery 对匹配的 AVObjects 进行计数) 展现了如何得到活跃玩家的计数:
AVQuery query = new AVQuery("Players"); query.whereEqualTo("status", "active"); //remove this line to count ALL query.countInBackground(new CountCallback() { @Override public void done(int count, AVException e) { if (e == null) { // Success, see count variable } else { // Failed } } });
AVQuery 支持 20 多个不一样的查询约束方法,如下是一些示例:
查询结果能够被排序,如清单 17(排序查询结果) 所示。为了对查询结果进行排序,能够调用其中一个 query orderBy...() 方法,指定做为排序依据的字段。
query.orderByAscending("name"); query.orderByDescending("name"); // For example: AVQuery query = new AVQuery("Players"); query.whereEqualTo("status", "active"); query.orderByAscending("lastName"); // By lastname ascending order query.findInBackground(new FindCallback() { @Override public void done(List<AVObject> players, AVException e) { if (players != null) { // Success - players contain active players } else { // Failed } } });
另外,须要注意的是,AVQuery 结果被缓存。您能够根据应用程序的需求,采用不一样的方式设置查询缓存策略。目前支持如下缓存策略:
设置缓存策略很简单。设置以前,首先要调用 find...() 方法,如清单 18 所示:
清单 18. 管理 CachePolicy
AVQuery query = new AVQuery("Players"); query.setCachePolicy(AVQuery.CachePolicy.NETWORK_ELSE_CACHE); query.findInBackground(new FindCallback() { @Override public void done(List<AVObject> players, AVException e) { if (e == null) { // Success - players contain active players } else { // Failed } } });
从 AVOS Cloud 云端删除数据对象也很简单。若是您已经有了对象实例,那么您就能够经过调用 AVObject 的 delete() 或 deleteInBackground()方法,从云中删除现有的 AVObject。这两个方法如清单 19 所示:
清单 19. 从云中删除 AVObject
pObject.delete(); pObject.deleteInBackground();
如您所料,delete() 是一个阻塞调用,这意味着您须要负责适当地在本身的工做线程上调用它。或者可使用带有或不带有回调的deleteInBackground() 方法来完成这一操做。
至此,咱们一直在使用 AVObject 对象和 AVQuery 查询。我还向您介绍了 AVUser(用户)、ACL 和角色。最后,我将示范如何在 AVOS Cloud 中使用文件的读、写和保存函数。
回想一下,您能够在 AVObject 中存储原始 byte[] 数据,这对于小规模数剧来讲是没问题的。但在存储较大的项目(如图像或文档)时,应该使用 AVFiles。
AVOS Cloud 云端的文件使用 AVFile 来表示,它提供得到文件名、URL、文件数据(假设数据可用)的方法。您也能够下载和上传文件,并访问其余一些辅助方法。
文件数据以 byte[] 语法表示。请注意,目前,给定的文件不得超过 10MB。在命名文件时,须要避免潜在的名称冲突,提供文件扩展名能够帮助 AVOS Cloud 处理文件的内容。
清单 20(保存一个 AVFile) 演示了保存一个 JPG 文件:
Drawable drawable = ...; Bitmap bitmap = (Bitmap)((BitmapDrawable) drawable).getBitmap(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] data = stream.toByteArray(); AVFile imageFile = new AVFile("image.jpg", data); imageFile.saveInBackground();
上述代码中最初的语句将位图转换成一个byte[]。而后,使用 AVFile.saveInBackground() 方法保存 byte[],这与将 AVObject 保存在服务器上的方法相似。
一旦将文件保存到 AVOS Cloud 上,必须将它与 AVOject 关联(放入 AVOject)。换句话说,AVFile 文件不是真正的独立对象,而且为了之后检索和使用,必须将它关联到给定的 AVObject 实例。这种局限可能会在将来版本中进行处理。
清单 21 将图像文件关联到一个 Player 对象:
AVObject po = new AVObject("Players"); po.put("name", "eortiz"); po.put("photo", imageFile); po.saveInBackground();
我已将文件关联到数据对象,而后使用 saveInBackgroud() 方法将对象保存在服务器上,我在前面已讨论过这一点。
清单 22 显示了如何检索与数据对象有关联的文件:
AVFile imageFile2 = (AVFile)po.get("photo"); imageFile2.getDataInBackground(new GetDataCallback() { public void done(byte[] data, AVException e) { if (data != null) { // Success; data has the file } else { // Failed } } });
从 AVObject 对象收到 AVFile 引用以后,我调用 getDataInBackground() 从服务器中检索 AVFile。请注意,我使用了回调GetDataCallback 来检索 AVOS Cloud 文件,并无使用 GetCallback,后者用于经过 AVQuery 检索 AVObject 对象。
AVOS Cloud API 很是全面,包括访问移动服务的类,好比实时消息,推送通知,使用地理数据,移动统计等等。在本文中,我经过介绍 AVOS Cloud API 实现数据和文件的云存储,简单介绍了如何使用 AVOS Cloud。咱们还了解了如何在 AVOS Cloud 云端存储和操纵用户、数据对象、文件和 ACL,这是进一步探索云平台进行移动开发的良好基础。