Retrofit的使用

Retrofit2.0的优势:1.性能最好,处理最快

                               2.简洁易用(RestfulAPI设计风格)

                               3.代码简化(更加高度的封装和注解写法)

                               4.解耦更彻底,易于其他框架联合使用

 

Step 1. 创建数据实体类(接收服务器返回数据)

  •              数据格式设计是根据返回的数据格式和数据解析方式(JSON/XML)定义
public class MovieModel {

    private String title;
    private List<SubjectModel> subjects;

    public String getTitle() {
        return title;
    }

    public List<SubjectModel> getSubjects() {
        return subjects;
    }

    static class SubjectModel {
        private String id;
        private String year;
        private String title;

        public SubjectModel(String id, String title, String year) {
            this.id = id;
            this.year = year;
            this.title = title;
        }

        public String getTitle() {
            return title;
        }

        public String getId() {
            return id;
        }

        public String getYear() {
            return year;
        }
    }
}

Step 2.创建用于描述网络请求的接口

  •             retrofit将http请求抽象成Java接口,采用注解描述网络请求参数和配置网络请求参数
  •             使用动态代理动态将该接口的注解“翻译”成一个http请求,最后执行Http请求
  •             接口的每个方法都是用注解标注

public interface RequestService {

    @GET("top250")
    Observable<MovieModel> getMovieData(@Query("start") int start, @Query("count") int count);
    // @GET注解的作用:采用Get方法发送网络请求

    // getMovieData() = 接收网络请求数据的方法
    // 其中返回类型为Observable<*>,*是接收数据的类(即上面定义的MovieModel类)
    // 如果想直接获得Responsebody中的内容,可以定义网络请求返回值为Observable<ResponseBody>

}

Step 3.创建Retrofit实例

  •            关于数据解析器(Converter):Retrofit支持多种数据解析方式(Gson, Jackson, Xml...)
  •            关于网络适配器(CallAdapter):Retrofit支持多种网络请求适配器方式:guava、Java8和rxjava 
public class RetrofitRequest {

    private static RetrofitRequest mRetrofitRequest;
    private static String baseUrl = "https://api.douban.com/v2/movie/";
    private static OkHttpClient mOkHttpClient;

    private static final int CONNECT_TIME_OUT = 7676;
    private static final int READ_TIME_OUT = 7676;

    //使用单例模式的懒汉模式,保证线程安全
    public static RetrofitRequest getInstance() {
        if (mRetrofitRequest == null) {
            synchronized (RetrofitRequest.class) {
                if (mRetrofitRequest == null) {
                    mRetrofitRequest = new RetrofitRequest();
                }
            }
        }
        return mRetrofitRequest;
    }

    //初始化拦截器,获取OkHttpClient对象并配置对应参数(缓存,超时策略)
    private RetrofitRequest() {
        Interceptor interceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request().newBuilder().build();
                return chain.proceed(request);
            }
        };

        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);

        mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIME_OUT, TimeUnit.MILLISECONDS)
                .readTimeout(READ_TIME_OUT, TimeUnit.MILLISECONDS)
                .addInterceptor(interceptor)
                .addInterceptor(loggingInterceptor)
                .build();

    }

    //创建Retrofit对象,并返回网络接口实例
    public RequestService createRetrofit() {
        Retrofit retrofit = new Retrofit
                .Builder()
                .client(mOkHttpClient)
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create()) //数据解析器
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//网络请求适配器
                .build();
        return retrofit.create(RequestService.class);
    }
}

Step 4.发送网络请求

  •            封装Observer,每次调用Observer只需要实现onNext()方法
public class RequestObserver<T> implements Observer<T> {
    private static final String TAG= RequestObserver.class.getSimpleName();

    private Disposable mDisposable;
    private Context mContext;
    private IObservableOnNext mOnNext;

    public RequestObserver(Context context, IObservableOnNext onNext) {
        mContext = context;
        mOnNext = onNext;
    }

    @Override
    public void onSubscribe(Disposable d) {
        mDisposable = d;
    }

    @Override
    public void onNext(T t) {
        mOnNext.onNext(t);
    }

    @Override
    public void onError(Throwable e) {
        Log.e(TAG, "ErrorMsg -> " + e.getMessage());
    }

    @Override
    public void onComplete() {
    }
}
  •              创建RequestMethod用于封装线程管理和订阅的过程及调用请求
public class RequestMethod {
   /**
     * 封装线程管理和订阅的过程
     */
    private static void buildSubcribe(Observable observable, Observer observer) {
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    public static void request(Observer observer, int start, int count) {
        buildSubcribe(RetrofitRequest.getInstance().createRetrofit().getMovieData(start, count), observer);
    }
}
  •             在界面调用Retrofit网络请求
/*在需要调用Retrofit网络请求的界面实现onNext()接口的方法来处理数据
* 然后将接口传入重写的RequestObserver,实现Observer的封装
* 每次subscribe的Observer只需要重写onNext()方法
*/
public class MainActivity extends AppCompatActivity implements IObservableOnNext {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       ...
        request.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                requestData();
            }
        });
    }

    private void requestData() {
        RequestMethod.request(new RequestObserver(this, this), 0, 10);
    }

    @Override
    public void onNext(Object obj) {
        ...
    }
}

 

retrofit如何与rxjava配合使用:

  1. 在retrofit.build().create(Api.class)之后会返回一个Observable
  2. observable在subscibe observer的时候会调用subscribeActual()方法
  3. 在callEnqueueObservable实现的subscribeActual()方法中,先获取retrofit.crate()未转换observable之前的call对象
  4. 传入call对象和observer来实例化自定义的callCallback类获取callback对象
  5. 在Observer的onSubscibe(callCallback)方法中传入callback进行订阅绑定  --> callCallback方法中implement Disposable,Callback<>, 重写了onResponese、onFailure、dispose、isDisposed四个方法,对返回的数据利用observer的onNext...接口方法传递
  6. call.enqueue(callCallback)方法进行异步请求(所以Observable需要设置线程切换)->

             a.通过静态delegate代理对网络请求接口的方法中的每个参数利用ParamterHandler进行解析
             b.根据ServiceMethod对象创建一个OkHttp的Request对象,并封装成OkHttp.call对象
             c.通过静态delegate代理利用OkHttp.call对象发起网络请求
                               
                     
为什么写个interface就能实现网络请求操作:Api api = retrofit.create(Api.class) ->

  1. 在retrofit.create()的方法中,根据传入的interface文件,通过roxy.newProxyInstance()动态生成网络请求接口的代理类,并将代理类的实例创建交给 InvocationHandler 类作为具体的实现,最终返回一个网络请求接口的动态代理对象
  2.  在api.getCall()的方法中,因为使用了动态代理,在调用getCall方法时会被拦截并转发到InvocationHandler的invoke(Object proxy:代理对象, Mehtod method:调用的方法, Object args:方法中的参数)中进行集中处理
  3.  在InvocationHandler()类中的具体实现分为三个步骤:

             a.通过loadServiceMethod(method)方法,读取网络接口中的方法,根据之前retrofit配置好的属性配置serviceMethod对象(单例模式:先判断是否存在ServiceMethod缓存)
             b.根据配置好的serviceMethod对象,创建OkHttpCall<>(serviceMethod, args)对象
             c.通过serviceMehtod.callAdapter.adapt(okHttpCall)方法,传入OkHttpCall对象,返回与CallAdapterFractory相对应的请求适配器(Observable/call)
                     
注意:

  1.  ServiceMethod几乎保存一个网络请求所需要的数据
  2.  发送网络请求时,OkHttpsCall需要从ServiceMethod中获取一个Request对象
  3.  解析数据时,需要通过ServiceMethod使用Converter(数据转换器)转换成Java对象进行数据解析
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值