Retrofit、RxJava和OkHttp使用

来源:互联网 发布:丝路英雄转生数据 编辑:程序博客网 时间:2024/05/17 22:47

本文主要介绍Retrofit、RxJava和OkHttp使用。需要添加依赖:

compile 'com.squareup.retrofit2:retrofit:2.3.0'compile 'io.reactivex.rxjava2:rxandroid:2.0.1'compile 'io.reactivex.rxjava2:rxjava:2.1.7'compile 'com.squareup.retrofit2:converter-gson:2.3.0'compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'

这里需要注意RxJava的版本问题,如果使用的是RxJava2,那么一定要使用adapter-rxjava2,否则在编码时会找不到相关的类。

Retrofit单独使用

  • Retrofit的请求是通过注解来实现的,需要先建一个接口类。
public interface RetrofitService {    @GET("book/search")    Call<Book> getBook(@Query("q") String name,                       @Query("tag") String tag,                       @Query("start") int start,                       @Query("count") int count);}

这是一个get请求,”book/search”是用来拼接请求url的,@Query(“tag”) String tag是用来传入请求参数的。

  • 得到Call对象执行网络请求
Retrofit retrofit = new Retrofit.Builder()                        .baseUrl("https://api.douban.com/v2/")                        .addConverterFactory(GsonConverterFactory.create())                        .build();                RetrofitService retrofitService = retrofit.create(RetrofitService.class);                Call<Book> call = retrofitService.getBook("西游记", null, 0, 1);                call.enqueue(new Callback<Book>() {                    @Override                    public void onResponse(Call<Book> call, Response<Book> response) {                        Book book = response.body();                        mTvContent.setText(book + "");                    }                    @Override                    public void onFailure(Call<Book> call, Throwable t) {                    }                });

这是Retrofit单独使用时候的用法。新建一个Retrofit对象,用这个Retrofit对象通过接口类可以得到一个Call对象,直接用这个Call对象发起网络请求,里面有两个回调方法供我们处理请求结果。

Retrofit和RxJava使用

  • 在接口类中再写一个方法
public interface RetrofitService {    @GET("book/search")    Call<Book> getBook(@Query("q") String name,                       @Query("tag") String tag,                       @Query("start") int start,                       @Query("count") int count);    @GET("book/search")    Observable<Book> getSearchBook(@Query("q") String name,                                   @Query("tag") String tag,                                   @Query("start") int start,                                   @Query("count") int count);}

可以看到,两个方法的写法都一样,只是返回值由Call对象变成了RxJava中的Observable对象。
关于RxJava的介绍,可以阅读以下这篇文章
给 Android 开发者的 RxJava 详解

  • 得到Observable对象执行网络请求
 Retrofit retrofitRxjava = new Retrofit.Builder()                        .baseUrl("https://api.douban.com/v2/")                        .addConverterFactory(GsonConverterFactory.create())                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                        .build();                RetrofitService retrofitService1 = retrofitRxjava.create(RetrofitService.class);                Observable<Book> observable = retrofitService1.getSearchBook("西游记", null, 0, 1);                observable.subscribeOn(Schedulers.io())                        .observeOn(AndroidSchedulers.mainThread())                        .subscribe(new Observer<Book>() {                            @Override                            public void onSubscribe(@NonNull Disposable d) {                                Log.d("AAA", "aaa");                            }                            @Override                            public void onNext(@NonNull Book book) {                                Log.d("BBB", "bbb");                                mTvContent.setText(book + "");                            }                            @Override                            public void onError(@NonNull Throwable e) {                                Log.d("DDD", "ddd");                            }                            @Override                            public void onComplete() {                                Log.d("CCC", "ccc");                            }                        });

基本步骤都是一样的,在构建Retrofit对象时,我们多添加了addCallAdapterFactory(RxJava2CallAdapterFactory.create())这一行代码,网络请求的回调方法也发生了改变。
四个回调方法,先执行onSubscribe()方法,表示订阅完成;然后执行onNext()方法,在这个方法中,我们可以获取网络请求的结果,并进行处理(在这个Demo中,请求得到一个Book对象,把Book对象中的文本内容显示在一个TextView中);最后执行onComplete()方法,表示整个网络请求过程完成。可以从下图的log日志中看到它们的执行顺序。
回调方法执行顺序

这是Demo请求成功之后的效果图。

网络请求成功

如果网络请求失败,则会执行onError()方法。这里我把网络关闭了,onError()方法报错显示无法连接上那个地址。注意这里只会执行onSubscribe()方法和onError()方法,不会再执行onNext()方法,也不会执行onComplete()方法。
回调方法执行顺序

Retrofit、RxJava和OkHttp一起使用

在了解了Retrofit、RxJava的使用之后,再加入一个OkHttp。其实这并不复杂,Retrofit内部也是通过OkHttp来实现网络请求的。我们可以用自己定义的OkHttpClient来代替Retrofit默认的OkHttpClient,然后在自定义的OkHttpClient中添加一些配置,比如配置网络请求的超时时间、配置缓存等等。
我们对Retrofit的网络请求进行一个简单的二次封装,这样在Activity或Fragment中使用起来更加方便,代码更加简洁,可维护程度更高。

新建一个RetrofitInstance类。在RetrofitInstance类中,创建一个OkHttpClient对象,配置了它的超时时间。再写一个单例模式,返回Retrofit对象,并且把自定义的OkHttpClient设置进去。(通过自定义的OkHttpClient,我们可以对网络请求做很多配置,具体请参考OkHttp使用教程)

public class RetrofitInstance {    private static Retrofit sInstance;    private static OkHttpClient mClient = new OkHttpClient().newBuilder()            .connectTimeout(10, TimeUnit.SECONDS)            .readTimeout(10, TimeUnit.SECONDS)            .writeTimeout(10, TimeUnit.SECONDS)            .build();    private RetrofitInstance() {    }    public static Retrofit getRetrofitInstance() {        if (sInstance == null) {            synchronized (RetrofitInstance.class) {                if (sInstance == null) {                    sInstance = new Retrofit.Builder()                            .client(mClient)                            .baseUrl("https://api.douban.com/v2/")                            .addConverterFactory(GsonConverterFactory.create())                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                            .build();                }            }        }        return sInstance;    }}

在Activity中使用Retrofit网络请求,不用每次都新建Retrofit对象,直接使用单例方法来获取就行了。回调方法和前面的也还是一样的。

RetrofitService retrofitService2 = RetrofitInstance.getRetrofitInstance().create(RetrofitService.class);                Observable<Book> bookObservable = retrofitService2.getSearchBook("西游记", null, 0, 1);                bookObservable.subscribeOn(Schedulers.io())                        .observeOn(AndroidSchedulers.mainThread())                        .subscribe(new Observer<Book>() {                            @Override                            public void onSubscribe(@NonNull Disposable d) {                                Log.d("AAA", "aaa");                            }                            @Override                            public void onNext(@NonNull Book book) {                                Log.d("BBB", "bbb");                                mTvContent.setText(book + "");                            }                            @Override                            public void onError(@NonNull Throwable e) {                                Log.d("DDD", e.toString());                            }                            @Override                            public void onComplete() {                                Log.d("CCC", "ccc");                            }                        });

这就是Retrofit、RxJava和OkHttp最基本的使用。也许看起来代码还是挺多的,那是因为RxJava的强大之处远不在此,遇到复杂的情况才能体现出它的优越性。如果你感兴趣,推荐你阅读一下这篇文章给 Android 开发者的 RxJava 详解。

最后附上Book实体类的代码(因为比较长)。

public class Book {    private int count;    private int start;    private int total;    private List<BooksBean> books;    public int getCount() {        return count;    }    public void setCount(int count) {        this.count = count;    }    public int getStart() {        return start;    }    public void setStart(int start) {        this.start = start;    }    public int getTotal() {        return total;    }    public void setTotal(int total) {        this.total = total;    }    public List<BooksBean> getBooks() {        return books;    }    public void setBooks(List<BooksBean> books) {        this.books = books;    }    public static class BooksBean {        private RatingBean rating;        private String subtitle;        private String pubdate;        private String origin_title;        private String image;        private String binding;        private String catalog;        private String pages;        private ImagesBean images;        private String alt;        private String id;        private String publisher;        private String isbn10;        private String isbn13;        private String title;        private String url;        private String alt_title;        private String author_intro;        private String summary;        private String price;        private List<String> author;        private List<TagsBean> tags;        private List<String> translator;        public RatingBean getRating() {            return rating;        }        public void setRating(RatingBean rating) {            this.rating = rating;        }        public String getSubtitle() {            return subtitle;        }        public void setSubtitle(String subtitle) {            this.subtitle = subtitle;        }        public String getPubdate() {            return pubdate;        }        public void setPubdate(String pubdate) {            this.pubdate = pubdate;        }        public String getOrigin_title() {            return origin_title;        }        public void setOrigin_title(String origin_title) {            this.origin_title = origin_title;        }        public String getImage() {            return image;        }        public void setImage(String image) {            this.image = image;        }        public String getBinding() {            return binding;        }        public void setBinding(String binding) {            this.binding = binding;        }        public String getCatalog() {            return catalog;        }        public void setCatalog(String catalog) {            this.catalog = catalog;        }        public String getPages() {            return pages;        }        public void setPages(String pages) {            this.pages = pages;        }        public ImagesBean getImages() {            return images;        }        public void setImages(ImagesBean images) {            this.images = images;        }        public String getAlt() {            return alt;        }        public void setAlt(String alt) {            this.alt = alt;        }        public String getId() {            return id;        }        public void setId(String id) {            this.id = id;        }        public String getPublisher() {            return publisher;        }        public void setPublisher(String publisher) {            this.publisher = publisher;        }        public String getIsbn10() {            return isbn10;        }        public void setIsbn10(String isbn10) {            this.isbn10 = isbn10;        }        public String getIsbn13() {            return isbn13;        }        public void setIsbn13(String isbn13) {            this.isbn13 = isbn13;        }        public String getTitle() {            return title;        }        public void setTitle(String title) {            this.title = title;        }        public String getUrl() {            return url;        }        public void setUrl(String url) {            this.url = url;        }        public String getAlt_title() {            return alt_title;        }        public void setAlt_title(String alt_title) {            this.alt_title = alt_title;        }        public String getAuthor_intro() {            return author_intro;        }        public void setAuthor_intro(String author_intro) {            this.author_intro = author_intro;        }        public String getSummary() {            return summary;        }        public void setSummary(String summary) {            this.summary = summary;        }        public String getPrice() {            return price;        }        public void setPrice(String price) {            this.price = price;        }        public List<String> getAuthor() {            return author;        }        public void setAuthor(List<String> author) {            this.author = author;        }        public List<TagsBean> getTags() {            return tags;        }        public void setTags(List<TagsBean> tags) {            this.tags = tags;        }        public List<String> getTranslator() {            return translator;        }        public void setTranslator(List<String> translator) {            this.translator = translator;        }        public static class RatingBean {            private int max;            private int numRaters;            private String average;            private int min;            public int getMax() {                return max;            }            public void setMax(int max) {                this.max = max;            }            public int getNumRaters() {                return numRaters;            }            public void setNumRaters(int numRaters) {                this.numRaters = numRaters;            }            public String getAverage() {                return average;            }            public void setAverage(String average) {                this.average = average;            }            public int getMin() {                return min;            }            public void setMin(int min) {                this.min = min;            }            @Override            public String toString() {                return "RatingBean{" +                        "max=" + max +                        ", numRaters=" + numRaters +                        ", average='" + average + '\'' +                        ", min=" + min +                        '}';            }        }        public static class ImagesBean {            private String small;            private String large;            private String medium;            public String getSmall() {                return small;            }            public void setSmall(String small) {                this.small = small;            }            public String getLarge() {                return large;            }            public void setLarge(String large) {                this.large = large;            }            public String getMedium() {                return medium;            }            public void setMedium(String medium) {                this.medium = medium;            }            @Override            public String toString() {                return "ImagesBean{" +                        "small='" + small + '\'' +                        ", large='" + large + '\'' +                        ", medium='" + medium + '\'' +                        '}';            }        }        public static class TagsBean {            private int count;            private String name;            private String title;            public int getCount() {                return count;            }            public void setCount(int count) {                this.count = count;            }            public String getName() {                return name;            }            public void setName(String name) {                this.name = name;            }            public String getTitle() {                return title;            }            public void setTitle(String title) {                this.title = title;            }        }        @Override        public String toString() {            return "BooksBean{" +                    "rating=" + rating +                    ", subtitle='" + subtitle + '\'' +                    ", pubdate='" + pubdate + '\'' +                    ", origin_title='" + origin_title + '\'' +                    ", image='" + image + '\'' +                    ", binding='" + binding + '\'' +                    ", catalog='" + catalog + '\'' +                    ", pages='" + pages + '\'' +                    ", images=" + images +                    ", alt='" + alt + '\'' +                    ", id='" + id + '\'' +                    ", publisher='" + publisher + '\'' +                    ", isbn10='" + isbn10 + '\'' +                    ", isbn13='" + isbn13 + '\'' +                    ", title='" + title + '\'' +                    ", url='" + url + '\'' +                    ", alt_title='" + alt_title + '\'' +                    ", author_intro='" + author_intro + '\'' +                    ", summary='" + summary + '\'' +                    ", price='" + price + '\'' +                    ", author=" + author +                    ", tags=" + tags +                    ", translator=" + translator +                    '}';        }    }    @Override    public String toString() {        return "Book{" +                "count=" + count +                ", start=" + start +                ", total=" + total +                ", books=" + books +                '}';    }}