數(shù)據(jù)存儲入門指南

AVOS Cloud 移動開發(fā) SDK 為 iOS、Android 和 WindowsPhone? 應(yīng)用程序提供了基于云的 API 和服務(wù),并且還提供了 JavaScript 和 REST API。使用 AVOS Cloud API,您可以極快地以最少工作量讓您的移動應(yīng)用程序支持云處理。集成了 AVOS Cloud SDK 的移動應(yīng)用程序可以輕松地在 AVOS Cloud 云上存儲數(shù)據(jù)對象和文件,發(fā)送并偵聽推送通知,管理用戶,處理地理位置數(shù)據(jù),并可以輕松獲得移動 IM 的能力。

開始之前
出于本文的目的,我假設(shè)您已經(jīng)非常熟悉使用 JSON、Android 和 Eclipse 進行移動應(yīng)用編程的基本概念。在您繼續(xù)閱讀本文之前,請訪問 avoscloud.com 并創(chuàng)建您的應(yīng)用程序。只需遵循注冊頁面中的簡單指令即可。

本文介紹了包含用戶、數(shù)據(jù)對象和文件的核心 API 類。您將學(xué)習(xí)如何使用訪問控制列表 (ACL),以及如何在數(shù)據(jù)對象上執(zhí)行 CRUD 操作,還有如何在 AVOS Cloud 云端存儲和檢索文件。示例均構(gòu)建于 AVOS Cloud SDK for Android 之上(請參閱Android開發(fā)指南)。

AVOS Cloud 控制臺

AVOS Cloud 控制臺可以幫助開發(fā)人員管理應(yīng)用程序。該控制臺為 API、文件和推送的通知提供了一般指標和應(yīng)用程序特定的使用指標。通過控制臺可管理應(yīng)用程序的基本設(shè)置信息,它還提供了數(shù)據(jù)瀏覽器,使開發(fā)人員能夠瀏覽(甚至編輯)所存儲的數(shù)據(jù)對象。數(shù)據(jù)瀏覽器對于調(diào)試非常有用。圖 1 是 AVOS Cloud 控制臺的屏幕截圖:

AVOS Cloud 控制臺
AVOS Cloud 控制臺

通過一個 App ID 和 App Key 對應(yīng)用程序進行身份驗證。為了獲得您的應(yīng)用程序 ID 和 Key,必須通過 AVOS Cloud 控制臺注冊您的應(yīng)用程序。在您的應(yīng)用程序上初始化 AVOS Cloud SDK 時,會用到這些信息。

AVObject 數(shù)據(jù)對象

在 AVOS Cloud 中,使用 “鍵-值” 對的容器 AVObject 表示數(shù)據(jù)。AVObject 可以存儲任何與 JSON 兼容的數(shù)據(jù),如清單 1 所示:

AVObject myObject = new AVObject("MyObject"); // Class Namemy
Object.put("name", “Feng Junwen");
myObject.put("twitterHandle", “jwfing");
myObject.put("followers", 123456);

AVObject 在實例化時被賦予一個 classname(類名稱)。在上述代碼中,類名稱是 "MyObject"。類名稱與關(guān)系數(shù)據(jù)庫中的表名稱相似,同一類的 AVObject 對象相當(dāng)于表中的行。

AVObject 暴露的方法類似于 Java Map 類中的方法,如 put、get 和 remove,以及大量特定于 AVObject 的其他方法。

AVObject名稱鍵 必須是字母數(shù)字的,作為一個指導(dǎo)方針,請對名稱鍵使用駝峰式大小寫 (camel-casing) 格式。值可以是存儲在 JSON 中的任何數(shù)據(jù)類型,也就是說,可以是數(shù)字、字符串、布爾值、數(shù)組、JSONObject.NULL、JSONObject 和 JSONArray。AVObject 所支持的其他數(shù)據(jù)類型是 Java Date 和 byte[] 數(shù)組。AVObject 還可以嵌套包含其他 AVObject。

清單 2 顯示了部分受支持的 AVObject 值數(shù)據(jù)類型:

// 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);

上述代碼創(chuàng)建了一個 AVObject,它在 AVOS Cloud 云端被存儲為一個對象。之后,我們可以保存、查詢和更新,并能從云端存儲中刪除。甚至可以在應(yīng)用程序離線時保存數(shù)據(jù),AVOS Cloud SDK 將數(shù)據(jù)保存在本地,直到重新建立網(wǎng)絡(luò)連接。

修改 AVObject

如果您熟悉移動應(yīng)用程序開發(fā),那么您就會知道,網(wǎng)絡(luò)操作等長時間操作一般都是在后臺完成,或在一個工作線程上完成,而不是在主系統(tǒng)的 UI 線程上完成。這樣可以避免主線程發(fā)生阻塞并影響用戶界面的響應(yīng)速度。稍后,在本文的后半部分,我會告訴您 AVOS Cloud 如何為后臺工作提供便利,從而保存、刪除和查找對象?,F(xiàn)在,考慮下面的同步 remove() 方法,可以使用它從 AVObject 刪除一個字段:

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

在刪除或添加字段后,或在更新當(dāng)前字段后,您可以在云端保存(或更新)數(shù)據(jù)對象,只需調(diào)用其中一個 AVObject 的 save...() 方法,我稍后會在本文中討論它們。

AVOS Cloud 用戶、角色和 ACL

在我告訴您如何在 AVOS Cloud 對象上執(zhí)行 CRUD 操作之前,您應(yīng)該了解一下 用戶、角色和 ACL(訪問控制列表)。這三個都是非常重要的概念,有助于保護您的應(yīng)用程序的數(shù)據(jù)對象。

用戶

名稱為 AVUser 的類代表一個用戶,并為應(yīng)用程序提供帳戶管理功能。每個應(yīng)用程序都有與之關(guān)聯(lián)的 AVUser 表。一個 AVUser 也是一個 AVObject,但具有更多的屬性,如用戶名、密碼和電子郵件。您可以添加任何您認為合適的其他數(shù)據(jù)值。

AVOS Cloud 中的匿名用戶
在 AVOS Cloud 中,匿名用戶是沒有用戶名或密碼的用戶。匿名用戶對于那些不要求用戶身份驗證的移動應(yīng)用程序功能非常有用。匿名用戶可以創(chuàng)建數(shù)據(jù)對象,但這些對象壽命很短,并且在匿名用戶登出之后就不再可用。

用戶可以注冊成為您應(yīng)用的 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 必須是應(yīng)用內(nèi)惟一的。如果 username 或 email 已經(jīng)被使用,那么注冊調(diào)用將會失敗。您應(yīng)該有一個通知用戶字段限制的機制,并提供一個重試的進程。

在注冊之后,用戶就可以登錄您的應(yīng)用,如清單 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
    }
  }
});

您可以通過調(diào)用 AVUser.save() 更新用戶信息。 但是請注意,只有 AVUser 的所有者可以修改其內(nèi)容,數(shù)據(jù)對于其他任何人都是只讀的。

AVOS Cloud SDK 會緩存當(dāng)前登錄的用戶。您可以通過調(diào)用 AVUser.currentUser() 查詢當(dāng)前用戶。currentUser 方法使您能夠快速訪問當(dāng)前用戶信息,那么如果當(dāng)前用戶會話沒有激活,您只需要根據(jù)提示輸入驗證。清單 5 (AVUser — 獲得當(dāng)前用戶)顯示了如何獲取當(dāng)前用戶:

AVUser currentUser = AVUser.getCurrentUser();
if (currentUser != null) {
  // current user is valid
} else {
  // current user not valid, ask for credentials
}

重置當(dāng)前用戶

在 AVOS Cloud 中,您可以通過調(diào)用 AVUser.logOut() 來重置當(dāng)前用戶,如清單 6(AVUser — 重置當(dāng)前用戶) 所示:

AVUser.logOut(); // static method

ACL

ACL 是關(guān)聯(lián)到數(shù)據(jù)對象的訪問權(quán)限(或控制)列表。AVACL 類允許您為給定的 AVObject 定義權(quán)限。使用 ACL,您可以定義對您的應(yīng)用程序數(shù)據(jù)對象的公共訪問,并且可以(通過角色)限制對特定用戶或用戶組的訪問。清單 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

您還可以為所有新創(chuàng)建的對象定義一個默認的 ACL。在清單 8 中,我已經(jīng)將可讀取和寫入的默認 ACL 設(shè)置為 public,清單 7 中的 publicACL定義。

清單 8. 設(shè)置默認的 ACL

// Set a default ACL for all newly created objects as public access
AVACL.setDefaultACL(publicACL, true);

雖然在這里沒有演示,但我們也可以使用 AVRole 類為用戶組授予訪問權(quán)限。接下來,我們將查看如何將 AVObject 數(shù)據(jù)對象保存到 AVOS Cloud 云,并在云端檢索它們。

保存 AVObject 數(shù)據(jù)對象

一旦創(chuàng)建并填充了 AVObject,就可以在 AVOS Cloud 云上保存。在云端保存數(shù)據(jù)對象實際上是利用 AVOS Cloud 最簡單的操作之一,其復(fù)雜性通常與數(shù)據(jù)表示、編組、網(wǎng)絡(luò)通信和傳輸?shù)扔嘘P(guān)聯(lián),AVOS Cloud SDK 完全隱藏了此復(fù)雜性。您需要使用 helper 方法來將數(shù)據(jù)對象實例映射到 AVObject,并映射回來,您需要決定是在您自己的線程上調(diào)度 AVOS Cloud 保存操作,還是使用 save-in-the-background 方法。

謹防系統(tǒng)線程阻塞!
回想一下,在移動應(yīng)用程序中,長時間的操作(如網(wǎng)絡(luò)、文件或長的計算)不應(yīng)該在主系統(tǒng)線程上完成。相反,應(yīng)在一個單獨的工作線程中執(zhí)行它們。阻塞系統(tǒng)線程會對應(yīng)用程序的用戶界面的響應(yīng)能力產(chǎn)生負面影響,有可能導(dǎo)致強行關(guān)閉您的應(yīng)用程序。

AVObject 提供兩個保存方法: save() 和 saveInBackground()。 saveInBackground()是建議的保存方法,因為它在自己的工作線程上運行保存操作。如果您選擇使用同步的save() 方法,需要注意的是,您需要在該方法自己的工作線程上調(diào)用該方法,以避免 UI 被阻塞。

清單 9 (在后臺保存 AVObject)顯示的代碼在后臺保存 AVObject 數(shù)據(jù)對象:

AVObject pObject = new AVObject("ExampleObject");
pObject.put("myNumber", number);
pObject.put("myString", name);
pObject.saveInBackground(); // asynchronous, no callback

清單 10(使用回調(diào),在后臺保存) 顯示的代碼使用了一個回調(diào),在后臺保存 AVObject 數(shù)據(jù)對象:

pObject.saveInBackground(new SaveCallback () {
    @Override
    public void done(AVException ex) {
        if (ex == null) {
            isSaved = true;
        } else {
            // Failed
            isSaved = false;
        }
    }
  });

save...() 方法的變形包括以下幾種:

  • 使用或不使用回調(diào),saveAllinBackground() 保存 AVObject。
  • saveAll(List<AVObject> objects) 保存 AVObjects 的列表。
  • saveAllinBackground(List<AVObject> objects) 在后臺保存 AVObjects 的列表。
  • saveEventually() 讓您能夠在未來某個時點將數(shù)據(jù)對象保存到服務(wù)器;如果 AVOS Cloud 云目前不可訪問,則使用該方法。

一旦在云上已成功保存了 AVObject ,就會為對象提供惟一的 Object-ID。此 Object-ID 非常重要,因為它惟一地標識了此 AVObject 實例。例如,您可以使用 Object-ID 確定是否已在云上成功保存該對象,以便檢索或刷新給定的對象實例和刪除特定的 AVObject。

檢索數(shù)據(jù)對象

這一節(jié)將探討查詢和檢索 AVOS Cloud 云上的數(shù)據(jù)對象的方法。您可以通過 object-ID 查詢一個 AVObject,您也可以使用屬性查詢一個或多個 AVObject 對象。如果您已經(jīng)有一個 AVObject,那么您可以通過從服務(wù)器提取最新的值,刷新或同步其內(nèi)容。我們將在以下代碼片段中探討所有這些選項。

提取 AVObjects

為了從 AVOS Cloud 云提取數(shù)據(jù)對象,使用 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
        }
    }
});

您也可以僅在需要時提取數(shù)據(jù),例如,提取一個 AVOS Cloud 對象關(guān)聯(lián)的 AVObject 對象,如清單 12(根據(jù)需要進行提取):

AVObject po = new AVObject("ExampleObject");
:
AVObject po2 = po.getAVObject("key");
// Fetch only if needed
try {
    po2.fetchIfNeeded();
} catch (AVException e) {
    e.printStackTrace();
}

另一個選項是在后臺根據(jù)需要執(zhí)行提取操作,并使用一個回調(diào)。為此,可以使用 AVObject 的 fetchIfNeededInBackground(GetCallback callback) 方法。

在某些情況下,您需要無條件地或僅在需要時一次提取一個 AVObject 集合。AVObject 為此提供了一組靜態(tài)方法,每個方法都將一個 AVObject 的列表作為輸入,然后返回一個 AVObject 的列表:

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

查詢數(shù)據(jù)對象

希望您現(xiàn)在已看到 AVOS Cloud API 的強大,但是別著急,它還有更多功能!除了提取數(shù)據(jù)對象之外,AVOS Cloud 還可以讓您使用 object-ID 或?qū)傩詠聿樵償?shù)據(jù)對象。要從云端查詢一個數(shù)據(jù)對象,可以使用 AVQuery。您可以使用 AVQuery 進行基本的和復(fù)雜的數(shù)據(jù)查詢,接收給定的對象或匹配對象的 List。

清單 13(使用 AVQuery 檢索給定的 AVObject) 顯示了如何在一個后臺線程中使用給定 object-ID 從服務(wù)器檢索特定的 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 類的所有數(shù)據(jù)對象。(沒有提供約束。)

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 還提供了一個方法來獲得匹配對象的計數(shù),不需要檢索對象本身,這非常有用。清單 16(使用 AVQuery 對匹配的 AVObjects 進行計數(shù)) 展示了如何獲得活躍玩家的計數(shù):

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) 查找點值在給定點附近,并且在給定最大距離內(nèi)的對象。

查詢結(jié)果可以被排序,如清單 17(排序查詢結(jié)果) 所示。為了對查詢結(jié)果進行排序,可以調(diào)用其中一個 query orderBy...() 方法,指定作為排序依據(jù)的字段。

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 結(jié)果被緩存。您可以根據(jù)應(yīng)用程序的需求,采用不同的方式設(shè)置查詢緩存策略。目前支持以下緩存策略:

  • IGNORE_CACHE:不使用緩存,這是默認的緩存策略。
  • CACHE_ONLY:只從緩存加載。如果沒有已緩存的結(jié)果,將會有一個 AVException。
  • NETWORK_ONLY:始終從網(wǎng)絡(luò)加載,但將結(jié)果保存到緩存。
  • CACHE_ELSE_NETWORK:首先查找緩存。如果失敗,則從網(wǎng)絡(luò)加載。如果緩存與網(wǎng)絡(luò)均不成功,結(jié)果將是 AVException。
  • NETWORK_ELSE_CACHE:首先查找網(wǎng)絡(luò)。如果失敗,則從緩存加載。如果緩存與網(wǎng)絡(luò)均不成功,結(jié)果將是 AVException。
  • CACHE_THEN_NETWORK:首先查找緩存。如果失敗,則從網(wǎng)絡(luò)加載。請注意,F(xiàn)indCallback 實際上被調(diào)用了兩次:第一次包括緩存的結(jié)果,然后包括網(wǎng)絡(luò)結(jié)果。該策略只能與 findInBackground 異步使用。

設(shè)置緩存策略很簡單。設(shè)置之前,首先要調(diào)用 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
        }
    }
});

刪除數(shù)據(jù)對象

從 AVOS Cloud 云端刪除數(shù)據(jù)對象也很簡單。如果您已經(jīng)有了對象實例,那么您就可以通過調(diào)用 AVObject 的 delete() 或 deleteInBackground()方法,從云中刪除現(xiàn)有的 AVObject。這兩個方法如清單 19 所示:

清單 19. 從云中刪除 AVObject

pObject.delete();
pObject.deleteInBackground();

如您所料,delete() 是一個阻塞調(diào)用,這意味著您需要負責(zé)適當(dāng)?shù)卦谧约旱墓ぷ骶€程上調(diào)用它?;蛘呖梢允褂脦в谢虿粠в谢卣{(diào)的deleteInBackground() 方法來完成這一操作。

使用文件

至此,我們一直在使用 AVObject 對象和 AVQuery 查詢。我還向您介紹了 AVUser(用戶)、ACL 和角色。最后,我將示范如何在 AVOS Cloud 中使用文件的讀、寫和保存函數(shù)。

回想一下,您可以在 AVObject 中存儲原始 byte[] 數(shù)據(jù),這對于小規(guī)模數(shù)劇來說是沒問題的。但在存儲較大的項目(如圖像或文檔)時,應(yīng)該使用 AVFiles。

AVOS Cloud 云端的文件使用 AVFile 來表示,它提供獲得文件名、URL、文件數(shù)據(jù)(假設(shè)數(shù)據(jù)可用)的方法。您也可以下載和上傳文件,并訪問其他一些輔助方法。

文件數(shù)據(jù)以 byte[] 語法表示。請注意,目前,給定的文件不得超過 10MB。在命名文件時,需要避免潛在的名稱沖突,提供文件擴展名可以幫助 AVOS Cloud 處理文件的內(nèi)容。

清單 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();

上述代碼中最初的語句將位圖轉(zhuǎn)換成一個byte[]。然后,使用 AVFile.saveInBackground() 方法保存 byte[],這與將 AVObject 保存在服務(wù)器上的方法類似。

一旦將文件保存到 AVOS Cloud 上,必須將它與 AVOject 關(guān)聯(lián)(放入 AVOject)。換句話說,AVFile 文件不是真正的獨立對象,并且為了以后檢索和使用,必須將它關(guān)聯(lián)到給定的 AVObject 實例。這種局限可能會在未來版本中進行處理。

清單 21 將圖像文件關(guān)聯(lián)到一個 Player 對象:

AVObject po = new AVObject("Players");
po.put("name", "eortiz");
po.put("photo", imageFile);
po.saveInBackground();

我已將文件關(guān)聯(lián)到數(shù)據(jù)對象,然后使用 saveInBackgroud() 方法將對象保存在服務(wù)器上,我在前面已討論過這一點。

清單 22 顯示了如何檢索與數(shù)據(jù)對象有關(guān)聯(lián)的文件:

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 引用之后,我調(diào)用 getDataInBackground() 從服務(wù)器中檢索 AVFile。請注意,我使用了回調(diào)GetDataCallback 來檢索 AVOS Cloud 文件,并沒有使用 GetCallback,后者用于通過 AVQuery 檢索 AVObject 對象。

結(jié)束語

AVOS Cloud API 非常全面,包括訪問移動服務(wù)的類,比如實時消息,推送通知,使用地理數(shù)據(jù),移動統(tǒng)計等等。在本文中,我通過介紹 AVOS Cloud API 實現(xiàn)數(shù)據(jù)和文件的云存儲,簡單介紹了如何使用 AVOS Cloud。我們還了解了如何在 AVOS Cloud 云端存儲和操縱用戶、數(shù)據(jù)對象、文件和 ACL,這是進一步探索云平臺進行移動開發(fā)的良好基礎(chǔ)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容