无法解决错误BEGIN_ARRAY但是BEGIN_OBJECT

时间:2018-05-04 08:27:21

标签: android json parsing retrofit2

我在使用改装调用解析时遇到问题。这不是重复的问题。我尝试了太多的谷歌搜索也尝试了很多解决方案但它在我的情况下不起作用。所以请不要投票这个问题。

错误

05-04 04:18:48.918 5290-5290/nexus.com.demogrph E/Error: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

这是我的回复数据

{
  "market_cap_by_available_supply": [
    [
      1367174841000,
      1500517590
    ],
    [
      1367261101000,
      1575032004
    ]
   ],
   "price_btc": [
    [
      1367174841000,
      1
    ],
    [
      1367261101000,
      1
    ]
   ],
  "price_usd": [
    [
      1367174841000,
      135.3
    ],
    [
      1367261101000,
      141.96
    ]
   ],
   "volume_usd": [
    [
      1367174841000,
      0
    ],
    [
      1367261101000,
      0
    ]
   ]
}

这里我尝试使用Retrofit调用API。

ApiClient.java

public class ApiClient {

    public static final String URL      = "https://graphs2.coinmarketcap.com/";
    public static Retrofit RETROFIT     = null;
//    https://api.coinmarketcap.com/v2/ticker/

    public static Retrofit getClient(){
        if(RETROFIT==null){
            OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(new LoggingInterceptor())
                    .build();
            RETROFIT = new Retrofit.Builder()
                    .baseUrl(URL)
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return RETROFIT;
    }
}

ApiService.interface

public interface ApiService {
    @GET("currencies/{id}")
    Call<List<PriceDatum>> getPriceData(@Path("id") String id);
}

PriceDatum.java

class PriceDatum implements Serializable {
    @SerializedName("market_cap_by_available_supply")
    @Expose
    private List<Integer> marketCapByAvailableSupply = null;
    @SerializedName("price_btc")
    @Expose
    private List<Integer> priceBtc = null;
    @SerializedName("price_usd")
    @Expose
    private List<Integer> priceUsd = null;
    @SerializedName("volume_usd")
    @Expose
    private List<Integer> volumeUsd = null;

    public List<Integer> getMarketCapByAvailableSupply() {
        return marketCapByAvailableSupply;
    }

    public void setMarketCapByAvailableSupply(List<Integer> marketCapByAvailableSupply) {
        this.marketCapByAvailableSupply = marketCapByAvailableSupply;
    }

    public List<Integer> getPriceBtc() {
        return priceBtc;
    }

    public void setPriceBtc(List<Integer> priceBtc) {
        this.priceBtc = priceBtc;
    }

    public List<Integer> getPriceUsd() {
        return priceUsd;
    }

    public void setPriceUsd(List<Integer> priceUsd) {
        this.priceUsd = priceUsd;
    }

    public List<Integer> getVolumeUsd() {
        return volumeUsd;
    }

    public void setVolumeUsd(List<Integer> volumeUsd) {
        this.volumeUsd = volumeUsd;
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
    List<PriceDatum> datalist;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ApiService apiService =
                ApiClient.getClient().create(ApiService.class);

        Call<List<PriceDatum>> call = apiService.getPriceData("bitcoin");
        call.enqueue(new Callback<List<PriceDatum>>() {
            @Override
            public void onResponse(Call<List<PriceDatum>> call, Response<List<PriceDatum>> response) {
                datalist = response.body();
                Log.d("data", "Number of movies received: " + datalist.size());
            }

            @Override
            public void onFailure(Call<List<PriceDatum>> call, Throwable t) {
                Log.e("Error",t.getMessage());
            }
        });
    }
}

2 个答案:

答案 0 :(得分:1)

试试这个我现在正在测试它... 使pojo类像下面的代码..

public class Response {
@SerializedName("market_cap_by_available_supply")
@Expose
public List<List<Integer>> market_cap_by_available_supply = null;
@SerializedName("price_btc")
@Expose
public List<List<Integer>> price_btc = null;
@SerializedName("price_usd")
@Expose
public List<List<Integer>> price_usd = null;
@SerializedName("volume_usd")
@Expose
public List<List<Integer>> volume_usd = null;

public List<List<Integer>> getMarket_cap_by_available_supply() {
    return market_cap_by_available_supply;
}

public void setMarket_cap_by_available_supply(List<List<Integer>> market_cap_by_available_supply) {
    this.market_cap_by_available_supply = market_cap_by_available_supply;
}

public List<List<Integer>> getPrice_btc() {
    return price_btc;
}

public void setPrice_btc(List<List<Integer>> price_btc) {
    this.price_btc = price_btc;
}

public List<List<Integer>> getPrice_usd() {
    return price_usd;
}

public void setPrice_usd(List<List<Integer>> price_usd) {
    this.price_usd = price_usd;
}

public List<List<Integer>> getVolume_usd() {
    return volume_usd;
}

public void setVolume_usd(List<List<Integer>> volume_usd) {
    this.volume_usd = volume_usd;
}

@Override
public String toString() {
    return
            "Response{" +
                    "price_usd = '" + price_usd + '\'' +
                    ",market_cap_by_available_supply = '" + market_cap_by_available_supply + '\'' +
                    ",price_btc = '" + price_btc + '\'' +
                    ",volume_usd = '" + volume_usd + '\'' +
                    "}";
}

}

然后制作如下的改造对象类..

public class ApiClient {
private final static String BASE_URL = "https://graphs2.coinmarketcap.com/";

public static ApiClient apiClient;
private Retrofit retrofit = null;
private Retrofit retrofit2 = null;

public static ApiClient getInstance() {
    if (apiClient == null) {
        apiClient = new ApiClient();
    }
    return apiClient;
}

//private static Retrofit storeRetrofit = null;

public Retrofit getClient() {
    return getClient(null);
}


private Retrofit getClient(final Context context) {

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient.Builder client = new OkHttpClient.Builder();
    client.readTimeout(60, TimeUnit.SECONDS);
    client.writeTimeout(60, TimeUnit.SECONDS);
    client.connectTimeout(60, TimeUnit.SECONDS);
    client.addInterceptor(interceptor);
    client.addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            return chain.proceed(request);
        }
    });

    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();


    return retrofit;
}

}

然后像下面那样制作api界面..

public interface ApiInterface {
@GET("currencies/bitcoin/")
Call<Response> getHero();

}

然后finnaly在主要活动中调用api,如下面的方法..

    private void getApiCall() {
    ApiInterface apiInterface = ApiClient.getInstance().getClient().create(ApiInterface.class);
    Call<Response> responseCall = apiInterface.getHero();
    responseCall.enqueue(new Callback<Response>() {
        @Override
        public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
            if (response.isSuccessful() && response != null && response.body() != null) {
                Log.d("data", response.body().toString());

            }
        }

        @Override
        public void onFailure(Call<Response> call, Throwable t) {

        }
    });

}

答案 1 :(得分:0)

查看响应,您的PriceDatum.java类中存在一些错误。进行以下更改 -

@SerializedName("market_cap_by_available_supply")
@Expose
public List<List<Integer>> market_cap_by_available_supply = null;
@SerializedName("price_btc")
@Expose
public List<List<Integer>> price_btc = null;
@SerializedName("price_usd")
@Expose
public List<List<Integer>> price_usd = null;
@SerializedName("volume_usd")
@Expose
public List<List<Integer>> volume_usd = null;
相关问题