【问题标题】:Fetch JSON data using retrofit and rxjava使用改造和 rxjava 获取 JSON 数据
【发布时间】:2018-12-29 01:48:01
【问题描述】:

我想使用改造和 rxjava 从 url https://api.myjson.com/bins/mxcsl/ 获取 json。 示例 json 是这样的:

{
"data": [
{
  "itemId": "1",
  "desc": "Batcave",
  "audio": "https://storage.googleapis.com/a/17.mp3"
},
{
  "itemId": "2",
  "desc": "Fight Club rules",
  "audio": "https://storage.googleapis.com/a/2514.mp3"
},
{
  "itemId": "3",
  "desc": "Make an offer",
  "audio": "https://storage.googleapis.com/a/47.mp3"
}]}

这是我的代码: 数据模型:

public class Data {

private String itemId;
private String desc;
private String audio;

public String getItem() {
    return itemId;
}

public String getDesc() {
    return desc;
}

public String getAudio() {
    return audio;
}}

这是界面:

public interface RequestInterface {

@GET("/bins/mxcsl/")
Observable<List<Data>> register();

}

我正在加载类似这样的内容:

private void loadJSON() {


    RequestInterface requestInterface = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build().create(RequestInterface.class);

    mCompositeDisposable.add(requestInterface.register()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe(this::handleResponse,this::handleError));
}

private void handleResponse(List<Data> androidList) {

    mAndroidArrayList = new ArrayList<>(androidList);
    mAdapter = new DataAdapter(mAndroidArrayList);
    mRecyclerView.setAdapter(mAdapter);
}

private void handleError(Throwable error) {

    Toast.makeText(this, "Error "+error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}

但我也收到了错误应该是 BEGIN_ARRAY,但实际上是 BEGIN_OBJECT

我不知道这是哪里出了问题。请帮忙。

【问题讨论】:

标签: android json rx-java retrofit


【解决方案1】:

你的类型

Observable<List<Data>> register();

错了。因为Json的第一层不是Array(而是带有字段data的对象,也就是数组)。 您应该为外部结构创建类

public class Outer{
    List<Data> data;
}

并在改造中指定,如可观察:

@GET("/bins/mxcsl/")
Observable<Outer> register();

【讨论】:

  • 我的 handleResponse 是这样的: private void handleResponse(List androidList) { mAndroidArrayList = new ArrayList(androidList); mAdapter = new DataAdapter(mAndroidArrayList); mRecyclerView.setAdapter(mAdapter); } 如何改变这个?
  • 像这样,这将是你的方法: private void handleResponse(Outer response) 里面你可以得到列表: mAndroidArrayList = response.data 其他一切都一样
【解决方案2】:

错误是因为 Retrofit 期望将 json 数组反序列化为 List

public interface RequestInterface {

    @GET("/bins/mxcsl/")
    Observable<List<Data>> register();
}

但是 json 响应是一个对象,其字段名为 data 是一个数组

{
 "data": [
 {
  "itemId": "1",
  "desc": "Batcave",
  "audio": "https://storage.googleapis.com/a/17.mp3"
 },
 {
  "itemId": "2",
  "desc": "Fight Club rules",
  "audio": "https://storage.googleapis.com/a/2514.mp3"
 },
 {
  "itemId": "3",
  "desc": "Make an offer",
  "audio": "https://storage.googleapis.com/a/47.mp3"
}]}

【讨论】:

    【解决方案3】:

    您的 api 响应是一个 JSONObject,其中包含一个 JSONArray 和密钥 data

    用另一个模型类包装你的数据列表

    public class ResponseData {
    
      @SerializedName("data")
      private List<Data> dataList;
    
      public List<Data> getDataList() {
        return dataList;
      }
    
      public void setDataList(List<Data> list) {
        dataList = list;
      }
    
    }
    

    RequestInterface 中使用ResponseData

    public interface RequestInterface {
    
      @GET("/bins/mxcsl/")
      Observable<ResponseData> register();
    
    }
    

    添加:

    由于您转换后的响应是 ResponseData 对象,因此您的 handleResponse 方法参数将是 ResponseData 类型。在 handleResponse 从 getter 方法中获取您期望的列表并将其设置为 Adapter

    handleResponse方法

    private void handleResponse(ResponseData responseData) {
      if( responseData != null){
         List<Data> dataList = responseData.getDataList();
         mAndroidArrayList = new ArrayList<>();
         if(dataList!= null){
            mAndroidArrayList.addAll(dataList);
         }
         mAdapter = new DataAdapter(mAndroidArrayList);
         mRecyclerView.setAdapter(mAdapter);
     }
    }
    

    【讨论】:

    • 我的 handleResponse 是这样的: private void handleResponse(List androidList) { mAndroidArrayList = new ArrayList(androidList); mAdapter = new DataAdapter(mAndroidArrayList); mRecyclerView.setAdapter(mAdapter);如何改变这个?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 2020-06-17
    • 2021-10-17
    • 2015-08-23
    相关资源
    最近更新 更多