Retrofit quick learning

Content mapping

1. Dependency library import

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

2. Basic use

2.1 define request interface


import hq.demo.net.model.WeatherBeans;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;

public interface NetService {

    @GET("?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json")
    Call<WeatherBeans> requestWeatherBeans();

    @POST("/")
    @FormUrlEncoded
    Call<WeatherBeans> requestWeatherBeans(
            @Field("app") String app,
            @Field("weaid") String weaid,
            @Field("appkey") String appkey,
            @Field("sign") String sign,
            @Field("format") String format);


}

Note here that @ FormUrlEncoded, if the post request is not added, an error will be reported as follows: java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)for method NetService.requestWeatherBeans

Why to add this note? I will analyze later.

 

2.2 get request network data

private void doGet() {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Call<WeatherBeans> call = netService.requestWeatherBeans();
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {


                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    Log.d("######beans", beans.toString());
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("cityName", bean.getCitynm());
                        Log.d("days", bean.getDays());
                    }
                }
            }

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

            }
        });
    }


//Result:
09-07 22:05:32.537 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:05:32.537 8546-8546/hq.demo.net D/days: 2018-09-05
09-07 22:05:32.537 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:05:32.537 8546-8546/hq.demo.net D/days: 2018-09-06
09-07 22:05:32.537 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:05:32.537 8546-8546/hq.demo.net D/days: 2018-09-07
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-08
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-09
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-10
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-11

2.3 post request

private void doPost() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Call<WeatherBeans> call = netService.requestWeatherBeans("weather.future","1","10003","b59bc3ef6191eb9f747dd4e83c99f2a4","json");
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {


                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("cityName", bean.getCitynm());
                        Log.d("days", bean.getDays());
                    }
                }
            }

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

            }
        });
    }


//Result:
09-07 22:11:37.351 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-05
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-06
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-07
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-08
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-09
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-10
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: Beijing
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-11

Because: http://api.k780.com/?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json Can accept get/post requests at the same time

3. Step analysis

The data requested from the network by using retrofit is parsed by using gson data. When creating retrofit through the builder mode, a GsonConverterFactory is added through addConverterFactory. GsonConverterFactory creates its instance through create(). By default, the overload method create (gson) of gson and create() is used, which can also be passed into a gson instance,

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

NetService netService = retrofit.create(NetService.class);

Then Retrofit takes over the custom interface by dynamically loading

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

 

4. Network request through OKHttpCall and OKHttp

In fact, it is through okhttp to make network requests


Call<WeatherBeans> call = netService.requestWeatherBeans();

call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("cityName", bean.getCitynm());
                        Log.d("days", bean.getDays());
                    }
                }
            }

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

            }
        });

       
       

Tags: Retrofit network JSON OkHttp

Posted on Thu, 02 Jan 2020 07:29:30 -0500 by sonofsam