基於 AVOS Cloud 的 Android 應用程序快速開發簡介

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 控制檯

AVOS Cloud 控制檯能夠幫助開發人員管理應用程序。該控制檯爲 API、文件和推送的通知提供了通常指標和應用程序特定的使用指標。經過控制檯可管理應用程序的基本設置信息,它還提供了數據瀏覽器,使開發人員可以瀏覽(甚至編輯)所存儲的數據對象。數據瀏覽器對於調試很是有用。圖 1 是 AVOS Cloud 控制檯的屏幕截圖:正則表達式

AVOS Cloud 控制檯

經過一個 App ID 和 App Key 對應用程序進行身份驗證。爲了得到您的應用程序 ID 和 Key,必須經過 AVOS Cloud 控制檯註冊您的應用程序。在您的應用程序上初始化 AVOS Cloud SDK 時,會用到這些信息。數據庫

AVObject 數據對象

在 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 將數據保存在本地,直到從新創建網絡鏈接。

修改 AVObject

若是您熟悉移動應用程序開發,那麼您就會知道,網絡操做等長時間操做通常都是在後臺完成,或在一個工做線程上完成,而不是在主系統的 UI 線程上完成。這樣能夠避免主線程發生阻塞並影響用戶界面的響應速度。稍後,在本文的後半部分,我會告訴您 AVOS Cloud 如何爲後臺工做提供便利,從而保存、刪除和查找對象。如今,考慮下面的同步 remove() 方法,可使用它從 AVObject 刪除一個字段:

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

在刪除或添加字段後,或在更新當前字段後,您能夠在雲端保存(或更新)數據對象,只需調用其中一個 AVObject 的 save...() 方法,我稍後會在本文中討論它們。

AVOS Cloud 用戶、角色和 ACL

在我告訴您如何在 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

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 數據對象

一旦建立並填充了 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...() 方法的變形包括如下幾種:

  • 使用或不使用回調,saveAllinBackground() 保存 AVObject。
  • saveAll(List objects) 保存 AVObjects 的列表。
  • saveAllinBackground(List objects) 在後臺保存 AVObjects 的列表。
  • saveEventually() 讓您可以在將來某個時點將數據對象保存到服務器;若是 AVOS Cloud 雲目前不可訪問,則使用該方法。

一旦在雲上已成功保存了 AVObject ,就會爲對象提供唯一的 Object-ID。此 Object-ID 很是重要,由於它唯一地標識了此 AVObject 實例。例如,您可使用 Object-ID 肯定是否已在雲上成功保存該對象,以便檢索或刷新給定的對象實例和刪除特定的 AVObject。

檢索數據對象

這一節將探討查詢和檢索 AVOS Cloud 雲上的數據對象的方法。您能夠經過 object-ID 查詢一個 AVObject,您也可使用屬性查詢一個或多個 AVObject 對象。若是您已經有一個 AVObject,那麼您能夠經過從服務器提取最新的值,刷新或同步其內容。咱們將在如下代碼片斷中探討全部這些選項。

提取 AVObjects

爲了從 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 的列表:

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

查詢數據對象

但願您如今已看到 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 方法和約束

AVQuery 支持 20 多個不一樣的查詢約束方法,如下是一些示例:

  • whereMatches(String key, String regex) 查找與所提供的正則表達式相匹配的字符串值。
  • whereStartsWith(String key, String prefix) 查找使用所提供的字符串開頭的字符串值。
  • whereContains(String key, String substring) 查找包含所提供的字符串的值。
  • whereGreaterThan(String key, Object value) 查找大於所提供的值的值。
  • whereWithinKilometers(String key, AVGeoPoint point, double maxDistance) 查找點值在給定點附近,而且在給定最大距離內的對象。

查詢結果能夠被排序,如清單 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 結果被緩存。您能夠根據應用程序的需求,採用不一樣的方式設置查詢緩存策略。目前支持如下緩存策略:

  • IGNORE_CACHE:不使用緩存,這是默認的緩存策略。
  • CACHE_ONLY:只從緩存加載。若是沒有已緩存的結果,將會有一個 AVException。
  • NETWORK_ONLY:始終從網絡加載,但將結果保存到緩存。
  • CACHE_ELSE_NETWORK:首先查找緩存。若是失敗,則從網絡加載。若是緩存與網絡均不成功,結果將是 AVException。
  • NETWORK_ELSE_CACHE:首先查找網絡。若是失敗,則從緩存加載。若是緩存與網絡均不成功,結果將是 AVException。
  • CACHE_THEN_NETWORK:首先查找緩存。若是失敗,則從網絡加載。請注意,FindCallback 實際上被調用了兩次:第一次包括緩存的結果,而後包括網絡結果。該策略只能與 findInBackground 異步使用。

設置緩存策略很簡單。設置以前,首先要調用 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,這是進一步探索雲平臺進行移動開發的良好基礎。

相關文章
相關標籤/搜索