RxJava结合Retrofit和Volley简单比较

作者: stefanJi | 来源:发表于2016-11-25 10:49 被阅读0次

    通过使用Retrofit+RxJavaVolley获取知乎日报消息,比较两者的使用区别。

    run.gif

    文中 RR:代指Retrofit+Rxjava

    主要两个方面使用

    1. 使用两者获取Json数据,使用Gson解析。
    2. 使用两者获取网络图片

    1.第一步添加RR和Volley的gradle依赖

    //google's volley
    compile 'com.mcxiaoke.volley:library:1.0.19'
    //RxAndroid
    compile 'io.reactivex:rxandroid:1.2.1'
    //RxJava
    compile 'io.reactivex:rxjava:1.2.3'
    //Retrofit
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    

    2.分析知乎首页Api返回的Json格式

    Api: http://news-at.zhihu.com/api/4/news/latest

    Json.png 分析图片来自GitHub [izzyleung](https://github.com/izzyleung)/**[ZhihuDailyPurify](https://github.com/izzyleung/ZhihuDailyPurify)**

    3.构建bean

    在AndroidStudio里我是使用一个Json2Pojo插件,可以直接将Json对象转换为适合Gson的JavaBean

    Json2Pojo

    在AS的插件管理里可以直接安装 Json2Pojo

     /**
     * 知乎当日消息
     */
    public class Stories {
        //供 Google Analytics 使用
        @SerializedName("ga_prefix")
        private String mGaPrefix;
        //url 与 share_url 中最后的数字(应为内容的 id)
        @SerializedName("id")
        private Long mId;
        //图像地址(官方 API 使用数组形式。目前暂未有使用多张图片的情形出现,曾见无 images 属性的情况,请在使用中注意 )
        @SerializedName("images")
        private List<String> mImages;
        //消息是否包含多张图片(仅出现在包含多图的新闻中)
        @SerializedName("multipic")
        private Boolean mMultipic;
        //消息标题
        @SerializedName("title")
        private String mTitle;
        //作用未知
        @SerializedName("type")
        private Long mType;
    
        public Stories(String mGaPrefix, Long mId, List<String> mImages, Boolean mMultipic, String mTitle, Long mType) {
            this.mGaPrefix = mGaPrefix;
            this.mId = mId;
            this.mImages = mImages;
            this.mMultipic = mMultipic;
            this.mTitle = mTitle;
            this.mType = mType;
        }
    
        public void setGaPrefix(String mGaPrefix) {
            this.mGaPrefix = mGaPrefix;
        }
    
        public void setId(Long mId) {
            this.mId = mId;
        }
    
        public void setImages(List<String> mImages) {
            this.mImages = mImages;
        }
    
        public void setMultipic(Boolean mMultipic) {
            this.mMultipic = mMultipic;
        }
    
        public void setTitle(String mTitle) {
            this.mTitle = mTitle;
        }
    
        public void setType(Long mType) {
            this.mType = mType;
        }
    
        public String getGaPrefix() {
            return mGaPrefix;
        }
    
        public Long getId() {
            return mId;
        }
    
        public List<String> getImages() {
            return mImages;
        }
    
        public Boolean getMultipic() {
            return mMultipic;
        }
    
        public String getTitle() {
            return mTitle;
        }
    
        public Long getType() {
            return mType;
        }
    
        @Override
        public String toString() {
            return "Stories{" +
                    "mGaPrefix='" + mGaPrefix + '\'' +
                    ", mId=" + mId +
                    ", mImages=" + mImages +
                    ", mMultipic=" + mMultipic +
                    ", mTitle='" + mTitle + '\'' +
                    ", mType=" + mType +
                    '}';
        }
    }
    

    4.定义Retrofit和Volley的单例管理

    获取Retrofit单例
    public class RetrofitManager {
        static final String BASE_URL = "http://news-at.zhihu.com/api/4/news/";
        private Retrofit retrofit;
        private static RetrofitManager ourInstance = new RetrofitManager();
    
        public static RetrofitManager getInstance() {
            return ourInstance;
        }
    
        private RetrofitManager() {
        }
    
        /**
         * 获取retrofit单例
         *
         * @return Retrofit single
         */
        public Retrofit getRetrofit() {
            if (retrofit == null) {
                retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
            }
            return retrofit;
        }
    }
    
    获取Volley RequestQueue单例
    public class VolleyManager {
        private RequestQueue requestQueue;
        private static VolleyManager ourInstance = new VolleyManager();
    
        public static VolleyManager getInstance() {
            return ourInstance;
        }
    
        private VolleyManager() {
        }
    
        /**
         * 获取 volley requestQueue 单例
         *
         * @param context activity
         * @return volley requestQueue
         */
        public RequestQueue getRequestQueue(Context context) {
            if (requestQueue == null) {
                requestQueue = Volley.newRequestQueue(context);
            }
            return requestQueue;
        }
    }
    

    5.定义Retrofit REST Api 接口

    //获取Json数据
    public interface GetNews {
        @GET("latest")
        Observable<Result> getNews();
    }
    
    //获取图片
    public interface GetBitmap {
        @GET
        Observable<ResponseBody> getPicFromNet(@Url String url);
    }
    
    这里使用RxJava形式的接口定义,直接返回 被观察者对象
    

    6.获取Json数据,并返回Result对象

    通过RR获取
    //get data by Retrofit & RxJava
    private void getDataByRetrofit() {
        progressBar.setVisibility(View.VISIBLE);        
        storiesAdapter.setGetPicByRR(true);// tell adapter get pic by retrofit
        //RR:Retrofit+RxJava
        Subscriber<Result> subscriber = new Subscriber<Result>() {
            @Override
            public void onCompleted() {
    
            }
    
            @Override
            public void onError(Throwable e) {
                progressBar.setVisibility(View.INVISIBLE);
                Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onStart() {
                super.onStart();
                storiesList.clear();
            }
    
            //设置数据到RecyclerView
            @Override
            public void onNext(Result result) {
                storiesList.addAll(result.getStories());
                storiesAdapter.notifyDataSetChanged();
                progressBar.setVisibility(View.INVISIBLE);
            }
        };
        //主要逻辑
        GetNews getNews = RetrofitManager.getInstance().getRetrofit().create(GetNews.class);
        getNews.getNews()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }
    
    通过Volley获取
    /**
     * get data by volley
     */
    private void getDataByVolley() {
        progressBar.setVisibility(View.VISIBLE);
        storiesAdapter.setGetPicByRR(false);// tell adapter get pic by volley
        //主要逻辑
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                RetrofitManager.BASE_URL + "latest",
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //Json to Bean
                        Gson gson = new Gson();
                        Result result = gson.fromJson(response, Result.class);
                        storiesList.addAll(result.getStories());
                        //设置数据到RecyclerView
                        storiesAdapter.notifyDataSetChanged();
                        progressBar.setVisibility(View.INVISIBLE);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(context, error.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
        VolleyManager.getInstance().getRequestQueue(this.getApplication()).add(stringRequest);
    }
    

    7.Adapter中获取图片

    通过RR获取
    //get pic by Retrofit and RxJava
            Action1<Bitmap> bitmapAction1 = new Action1<Bitmap>() {
                @Override
                public void call(Bitmap bitmap) {
                    holder.ivImg.setImageBitmap(bitmap);
                }
            };
            String url = stories.getImages().get(0);
            GetBitmap getBitmap = RetrofitManager.getInstance().getRetrofit().create(GetBitmap.class);
            getBitmap.getPicFromNet(url)
                    .map(new Func1<ResponseBody, Bitmap>() {
                        @Override
                        public Bitmap call(ResponseBody responseBody) {
                            //decode pic
                            return BitmapFactory.decodeStream(responseBody.byteStream());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(bitmapAction1);
    
    通过Volley获取
    //get pic by volley
            ImageLoader imageLoader = new ImageLoader(VolleyManager.getInstance()
                        .getRequestQueue(context.getApplicationContext())
                    , new ImageLoader.ImageCache() {
                @Override
                public Bitmap getBitmap(String url) {
                    return null;
                }
    
                @Override
                public void putBitmap(String url, Bitmap bitmap) {
    
                }
            });
            ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(holder.ivImg, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
            String url = stories.getImages().get(0);
            imageLoader.get(url, imageListener);
    
    Project目录.png

    8.总结

    这里只是从简单的使用层面上对比了RR和Volley两者使用上的不同,之前获取网络数据的任务都是交给Volley来做。
    有时获取了A数据之后,马上需要进行下一步包装分析A之后获取B数据。
    如果是在Volley中就会出现嵌套的逻辑;在RxJava中使用Retrofit就可以使用它的map(或flatMap)进行A数据的包装分析,之后返回B数据的,就不会出现嵌套的逻辑。

    以上只是小生简单的对比,用以自身理解RxJava,有什么不对的地方欢迎各位指出 _

    9.整体代码放在GitHub上,欢迎浏览

    相关文章

      网友评论

        本文标题:RxJava结合Retrofit和Volley简单比较

        本文链接:https://www.haomeiwen.com/subject/qoxipttx.html