3

私は、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>などの他のオブジェクトにも同様に適用できます。QuestionAnswer

Chrome で Postman 拡張機能をテストした後、次のことがわかりました。これはつまずきです。使用する REST API に関係なく、一般的なラッパーが応答で返されますがitems、JSON 出力内のフィールドには次の配列が含まれています。Siteこの場合。

私は、返されない共通ラッパーにフィールドがあると推測しましたtype 。ここでのアイデアは、後で少しチートすることです...そして、それはフィルターの一部ではないため、/filter/createAPI を作成し、次のように 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 ライブラリで期待を少し高く設定しすぎたのでしょうか?

4

1 に答える 1