私は、Google Android のユーザー エクスペリエンスに従って、API と対話するための適切な Android アプリケーションを作成中です。
アプリケーションは Retrofit を使用します (REST-api メカニズムを簡単にするため)。
これで、各 API 呼び出しに対応する Java クラスが作成されました。
たとえば、この方法で APISite.java
を処理するクラス:/sites
これは簡潔にするために要約されています。
public class Site{
@SerializedName("api_site_parameter") String mApiSiteParameter = "";
// snip
}
インターフェイスは、このように接続されています。ISites.java
public interface ISites{
@GET("/sites")
public void getAllSites(@Query("filter") String filterName,
Callback<List<Site>> cbAllSites);
}
大きな問題は、一般的なラッパーが使用されているため、どのようにして Retrofit をコレクションに戻すことができるかということです。これは、List<Site>
などの他のオブジェクトにも同様に適用できます。Question
Answer
Chrome で Postman 拡張機能をテストした後、次のことがわかりました。これはつまずきです。使用する REST API に関係なく、一般的なラッパーが応答で返されますがitems
、JSON 出力内のフィールドには次の配列が含まれています。Site
この場合。
私は、返されない共通ラッパーにフィールドがあると推測しましたtype
。ここでのアイデアは、後で少しチートすることです...そして、それはフィルターの一部ではないため、/filter/create
API を作成し、次のように Retrofit の呼び出しへの呼び出しの一部としてそれを適用しますRestAdapter
。
RestAdapter ra = new RestAdapter.Builder()
.setServer("http://api.stackexchange.com/2.1")
.setLogLevel(LogLevel.FULL)
.build();
ISites sites = ra.create(ISites.class);
sites.getAllSites("my_commonwrapper_filter", Callback<Site>(){
@Override
public void failure(RetrofitError argRetrofitError){
}
@Override
public void success(List<Site> sites, Response response){
}
});
SO でここで回答された Gson のカスタムTypeAdapterFactory
を研究した後、ここで何か不足していますか?これは私がこれまでに持っているものです。
SEWrapper.java
次のようなクラスを作成しました。
public class SEWrapper{
@SerializedName("items") List<Class ?> mListItems;
@SerializedName("type") String mJsonObjType;
}
SEWrapper
の代わりに使用するように Site.java ソースをSite
変更し、REST 呼び出しを変更しました。
このコードは、StackOverflow に関する質問から採用されています。
private class SEWrapperTypeAdapterFactory extends CustomizedTypeAdapterFactory<SEWrapper> {
private SEWrapperTypeAdapterFactory() { super(SEWrapper.class); }
@Override
protected void beforeWrite(SEWrapper source, JsonElement toSerialize) {
// Ignored for now as all this is Read Only operation!
}
@Override
protected void afterRead(JsonElement deserialized) {
String typeOfJsonObj = deserialized.getAsJsonObject().get("type").getAsString();
if (typeOfJsonObj.equalsIgnoreCase("site")){
JsonArray jSiteArray = deserialized.getAsJsonObject().get("items").getAsJsonArray();
// Convert that to List<Site> type which I cannot figure out
}
}
このつまずきを回避する方法についてのアイデアがありません。
理論的には、Retrofit のResponse
オブジェクトを返すように書き直して、各 JSON オブジェクトを手動で解析し、その型の List を作成することSite
もできますが、返される API オブジェクトごとに面倒で時間がかかります。
私はこれを間違った方法で行っているのでしょうか、それとも Retrofit ライブラリで期待を少し高く設定しすぎたのでしょうか?