Retrofit、RxJava和OkHttp使用

本文主要介绍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 +
                '}';
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值