Retrofit 返回空 arraylist 但给出了有效的 POJO 和 Json 来处理(尝试了其他问题但对它们起作用的答案不在 mne 上)

Retrofit returning empty arraylist but given valid POJO and Json to work with (tried other questions but the answers that worked on them don't on mne)

这里有人知道如何对 Django Rest Framework 项目进行改造吗?我已经按照记录在两端完成了我需要做的一切,它返回了我在 http://www.jsonschema2pojo.org/ 上生成的 Pojos 的有效 Json,但出于某种奇怪的原因,Retrofit 一直从 [=34] 返回一个空列表=] 给出的结果我需要这个才能上线所以我明天向我的主管演示我的工作..请帮助 P.S:toast 中的所有内容都显示 0 值、我的 storePlaces arraylist 从中获取数据的列表的大小、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(我已经更新它以限制用户对他们没有创建的对象的只读访问权限,所以所有者部分是一个新事物..但是JSONchrome 的视图扩展验证了 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 开发服务器控制台输出的最后几个请求是针对我的应用程序的,其余的来自浏览器)

您不能 return 方法的异步回调的结果。当方法 return 执行时,您的 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
        }
    }
)

编辑 简要说明

这是观察者模式的一个例子。

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

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