Android 开头的改造查询 url

Android retrofit query at the beginning of the url

我正在尝试访问 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.onResponse(SearchResultAcitivity.java:119)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.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 Documentation 或官方 Doc page url 应该是这样

http://partners.skyscanner.net/apiservices/pricing/v1.0/?apikey=API_KEY&country=COUNTRY&currency=CURRENCY&...etc

但是 Retrofit 将我的 api 关键参数放在 url:

的末尾

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

我设置的界面:

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 );
}

它在我的内部看起来如何 activity:

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,所以我一直在寻找解决这个问题的方法,但找不到适合我的方法。

我对 Retrofit 有一点经验,所以我请求你的帮助。

谢谢。

Multiple Queries with Retrofit

你可以看到这个link。我认为你应该使用 @QueryMap

而不是使用 @Path