我正在尝试访问 Skyscanner 的 API 并获取票证数据,我可以使用基本的 Asynctask 来做到这一点,但我想切换到 Retrofit 并且遇到了一个问题:
09-26 16:00:17.104 1830-2314/com.example.app D/OkHttp: --> POST http://partners.api.skyscanner.net/apiservices/pricing/v1.0/US/USD/en-us/SFO/LAX/2016-12-05/2016-12-14/iata/Economy/1/0/0/false?apiKey=xxxxxxxxxxxx http/1.1 (0-byte body)
09-26 16:00:17.134 1830-1856/com.example.app W/EGL_emulation: eglSurfaceAttrib not implemented
09-26 16:00:17.134 1830-1856/com.example.app W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xdf0b4ca0, error=EGL_SUCCESS
09-26 16:00:17.190 1830-1856/com.example.app W/EGL_emulation: eglSurfaceAttrib not implemented
09-26 16:00:17.190 1830-1856/com.example.app W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xdf13f000, error=EGL_SUCCESS
09-26 16:00:17.220 1830-1830/com.example.app E/RecyclerView: No adapter attached; skipping layout
09-26 16:00:17.348 1830-1830/com.example.app E/RecyclerView: No adapter attached; skipping layout
09-26 16:00:17.487 1830-1856/com.example.app E/Surface: getSlotFromBufferLocked: unknown buffer: 0xdfdd6380
09-26 16:00:17.492 1830-1856/com.example.app D/OpenGLRenderer: endAllStagingAnimators on 0xdf1cfb00 (RippleDrawable) with handle 0xdedeb8f0
09-26 16:00:17.762 1830-2314/com.example.app D/OkHttp: <-- 404 Not Found http://partners.api.skyscanner.net/apiservices/pricing/v1.0/US/USD/en-us/SFO/LAX/2016-12-05/2016-12-14/iata/Economy/1/0/0/false?apiKey=xxxxxxxxxxxx (658ms, 0-byte body)
09-26 16:00:17.785 1830-1856/com.example.app E/Surface: getSlotFromBufferLocked: unknown buffer: 0xdfdd6930
09-26 16:00:17.788 1830-1830/com.example.app D/AndroidRuntime: Shutting down VM
09-26 16:00:17.789 1830-1830/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app, PID: 1830
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.example.app.model.TicketData.getItineraries()' on a null object reference
at com.example.app.activities.SearchResultAcitivity$1.onResponse(SearchResultAcitivity.java:119)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
根据 Skyscanner 的GitHub 文档 或官方文档页面 url 应该是这样的
但是 Retrofit 将我的 api 关键参数放在 url 的末尾:
我设置的界面:
public interface GetFlightDetails {
@POST("{country}/{currency}/{locale}/{originPlace}/{destinationPlace}/{outboundPartialDate}/{inboundPartialDate}/{locationschema}/{cabinclass}/{adults}/{children}/{infants}/{groupPricing}")
Call<TicketData> getFlightList (@Path("country") String country,
@Path("currency") String currency,
@Path("locale") String locale,
@Path("originPlace") String originPlace,
@Path("destinationPlace") String destinationPlace,
@Path("outboundPartialDate")String outboundPartialDate,
@Path("inboundPartialDate") String inboundPartialDate,
@Path("locationschema") String locationschema,
@Path("cabinclass") String cabinclass,
@Path("adults") int adults,
@Path("children") int children,
@Path("infants") int infants,
@Path("groupPricing") boolean groupPricing,
@Query("apiKey") String apiKey );
}
它在我的活动中的外观:
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
httpClient.interceptors().add(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient.build())
.build();
GetFlightDetails api = retrofit.create(GetFlightDetails.class);
Call<TicketData> mresponse = api
.getFlightList(country, currency, locale, from, to,
departDate.substring(0,10), returnDate.substring(0,10),
locationSchema, cabinClass, adult, children, infants, false, API_KEY);
mresponse.enqueue(new Callback<TicketData>()
{
@Override
public void onResponse(Call<TicketData> call, Response <TicketData> response) {
if (response == null) return;
else
{
progress.cancel();
TicketData ticketData = response.body();
RecyclerAdapter adapter = new RecyclerAdapter(getApplicationContext(), ticketData);
mRecyclerView.setAdapter(adapter);
}
}
@Override
public void onFailure(Call<TicketData> call, Throwable t)
{
progress.setMessage("Retrofit Error Occurred");
}
});
根据 Retrofit 的文档,我不能在开始时使用 @Query 而不是在那之后添加 @Path,所以我一直在寻找解决这个问题的方法,但找不到任何适合我的方法。
我对改造有一点经验,因此我请求你的帮助。
谢谢。