改造返回空的arraylist,但给予有效的POJO和Json合作(尝试了其他问题,但是对他们有效的答案不在mne上)

时间:2016-04-17 10:13:58

标签: android json retrofit2 gson

有没有人知道如何使用Django Rest Framework项目进行改造?我已经完成了我需要的所有内容,如同记录的那样,它返回了我在http://www.jsonschema2pojo.org/生成Pojos的有效Json,但由于一些奇怪的原因,Retrofit继续从Json结果返回一个空列表,这是我需要的这是为了现场,所以我明天将我的工作演示给我的主管..请帮助 P.S:Toast中的所有内容都显示一个0值,我的storePlaces arraylist从List中获取数据的大小,storePlaces Arraylist本身,以及Retrofit返回的状态代码..希望这是有用的 这是我的代码:

API端点:

// Request method and URL specified in the annotation
// Callback for the parsed response is the last parameter

@GET("/api/products/")
Call<List<Store>> getStoreList(@Query("format") String format);

@GET("/api/stores/{store_id}/")
Call<Store> getClickedStore(@Path("store_id") Integer store_id, @Query("format") String format);

POJO:

public class Store extends RealmObject {

@SerializedName("id")
@Expose
private int id;
@SerializedName("name")
@Expose
private String name;
@SerializedName("picture")
@Expose
private String picture;
@SerializedName("Phone")
@Expose
private String Phone;
@SerializedName("email")
@Expose
private String email;
@SerializedName("website")
@Expose
private String website;
@SerializedName("longitude")
@Expose
private String longitude;
@SerializedName("latitude")
@Expose
private String latitude;
@SerializedName("address")
@Expose
private String address;

/**
 *
 * @return
 *     The id
 */
public int getId() {
    return id;
}

/**
 *
 * @param id
 *     The id
 */
public void setId(int id) {
    this.id = id;
}

/**
 *
 * @return
 *     The name
 */
public String getName() {
    return name;
}

/**
 *
 * @param name
 *     The name
 */
public void setName(String name) {
    this.name = name;
}

/**
 *
 * @return
 *     The picture
 */
public String getPicture() {
    return picture;
}

/**
 *
 * @param picture
 *     The picture
 */
public void setPicture(String picture) {
    this.picture = picture;
}

/**
 *
 * @return
 *     The Phone
 */
public String getPhone() {
    return Phone;
}

/**
 *
 * @param Phone
 *     The Phone
 */
public void setPhone(String Phone) {
    this.Phone = Phone;
}

/**
 *
 * @return
 *     The email
 */
public String getEmail() {
    return email;
}

/**
 *
 * @param email
 *     The email
 */
public void setEmail(String email) {
    this.email = email;
}

/**
 *
 * @return
 *     The website
 */
public String getWebsite() {
    return website;
}

/**
 *
 * @param website
 *     The website
 */
public void setWebsite(String website) {
    this.website = website;
}

/**
 *
 * @return
 *     The longitude
 */
public String getLongitude() {
    return longitude;
}

/**
 *
 * @param longitude
 *     The longitude
 */
public void setLongitude(String longitude) {
    this.longitude = longitude;
}

/**
 *
 * @return
 *     The latitude
 */
public String getLatitude() {
    return latitude;
}

/**
 *
 * @param latitude
 *     The latitude
 */
public void setLatitude(String latitude) {
    this.latitude = latitude;
}

/**
 *
 * @return
 *     The address
 */
public String getAddress() {
    return address;
}

/**
 *
 * @param address
 *     The address
 */
public void setAddress(String address) {
    this.address = address;
}

}

调用Retrofit的方法:

private ArrayList<Store> getDataSet() {

    Gson gson = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            })
            .create();

    Retrofit retrofitClient = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();

    // create a new service call variable from the interface with retrofitClient
    ShoplistApiEndpointInterface apiService = retrofitClient.create(ShoplistApiEndpointInterface.class);

    //create a new APICall variable of the api interface with its type being that of the call method you'll invoke from the interface
    Call<List<Store>> storeListCall = apiService.getStoreList(FORMAT_SPECIFIER);

    // make the call asynchronously by calling enqueue on the Call type
    //FIXME: chane serverside encoding is option 1 (type:app/json, encoding: utf8)
    storeListCall.enqueue(new Callback<List<Store>>() {

        @Override
        public void onResponse(Call<List<Store>> call, Response<List<Store>> response) {
            // get status code from the HTTP response code
            statusCode = response.code();
            // add the parsed response body data (parsed pojo object list in this case)
            // to the arrayList with the addAll(Collection<type>) method
            List<Store> results = response.body();
            ressize = response.body().size();
            int initialSize = storePlaces.size();
            storePlaces.addAll(initialSize, results);
        }

        @Override
        public void onFailure(Call<List<Store>> call, Throwable t) {
            // log the error here
            Log.e(LOG_TAG, "Failed to download Place list", t);
            Toast.makeText(getActivity(), R.string.failed_to_download_list, Toast.LENGTH_SHORT).show();
        }
    });

    Log.d(LOG_TAG, "Success, new data set is of size " + storePlaces.size() + " with status code: " + statusCode + " from source sized: " + ressize);

    return storePlaces;
}

JSON(我已经对其进行了更新,以限制用户不仅仅可以访问他们未创建的对象,因此所有者部分是一个新东西..但是Chrome的JSONview扩展验证了第一个和第一个版本的JSON)

   [
{
id: 1,
name: "Shoprite Zm",
picture: "http://127.0.0.1:8000/api/stores/productphotos/stores/serializer_snPGr8P.PNG",
Phone: "0255447854",
email: "fabf@ducj.omf",
website: "http://www.f.rd",
latitude: "0.000000",
longitude: "0.000000",
address: "noiibuiuwefd",
owner: 1
},
{
id: 2,
name: "Game fr",
picture: "http://127.0.0.1:8000/api/stores/productphotos/stores/orcl.PNG",
Phone: "467565",
email: "fnini@irni.nur",
website: "http://afninni.gg.rtd",
latitude: "0.000000",
longitude: "0.000000",
address: "horvsawhgfl,md boisdrl",
owner: 1
},
{
id: 3,
name: "Ret",
picture: null,
Phone: "ajiwenpgoernen",
email: "fihIANPI@FNIIW.VID",
website: "http://FWIHFIFNVOI.fnawifni.afvn9weo.FNWIA",
latitude: "0.000000",
longitude: "0.000000",
address: "fawzsuvba.wfQSFBON",
owner: 1
}
]

(Django开发服务器控制台输出的最后几个请求是针对我的应用程序,其余来自浏览器)

Image showing that both my browser and app successfully connected

1 个答案:

答案 0 :(得分:1)

您无法从方法返回异步回调的结果。当方法返回时,storePlaces总是为空,因为Retrofit http调用尚未完成。

解决这个问题的方法是将您自己的回调方法作为getDataSet()方法的参数传递。首先定义一个通用的回调接口:

public interface Callback<T> {
    void next(T result);
}

然后更改您的getDataSet()方法:

public void getDataSet(Callback<List<Store>> callback) {

    //...

    @Override
    public void onResponse(Call<List<Store>> call, Response<List<Store>> response) {

        // get status code from the HTTP response code
        statusCode = response.code();
        // add the parsed response body data (parsed pojo object list in this case)
        // to the arrayList with the addAll(Collection<type>) method
        List<Store> results = response.body();
        ressize = response.body().size();
        int initialSize = storePlaces.size();
        storePlaces.addAll(initialSize, results);

        callback.next(storePlaces);
    }

    //...
}

现在,在您使用getDataSet方法的代码中,您可以将其称为:

getDataSet(new Callback<List<Store>>() {
        @Override
        public void next(List<Store> results) {
            // use the results
        }
    }
)

编辑简要说明

这是 Observer Pattern 的示例。

您使用Observer(您的Retrofit运行方法)注册Subject(Callback接口的具体实现)。当Subject完成任务后,它会通知Observer然后运行其代码。

您可以在需要从中获取结果的异步操作的情况下使用此模式。它还在整个Android框架中用于注册监听器,如OnClickListener。