美文网首页AndroidAndroid开发Android开发
Retrofit2.0+RxJava+MVP整合实践

Retrofit2.0+RxJava+MVP整合实践

作者: 张文文同学 | 来源:发表于2016-12-27 17:10 被阅读522次

    Retrofit、RxJava、MVP设计模式这些技术出来有挺长一段时间了,之前也研究过分别的使用,但是没整合一起使用过。

    Retrofit 是一个Square开发的类型安全的RESTful安卓客户端请求库。这个库为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架 。

    什么是RESTful呢?RESTful是一种软件架构风格,但不是设计标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    RESTFul实现大概需要一下步骤:

    1. 用URL来表示一个Object对象,例如:用www.baidu.com表示一个购物生成的订单对象

    2. 用标准的HTTP协议完成逻辑操作,例如:我们用HTTP GET完成获取订单内容的操作、用HTTP POST来完成更新一个订单内容的操作等。

    3. 无状态,意思就是服务器端不保留任何操作和事务的状态,也不存在类似事务的回滚操作。

    RxJava在网络上有很多的解释和Demo,这里就不再做过多的介绍了,没了解的可以参考这一篇文章:给 Android 开发者的 RxJava 详解,写的非常好,非常强大。

    MVP设计模式已经出来有一段时间了,具体的工作流程如下图所示:

    具体的工作流程就再说一下:

    1. presenter负责所有逻辑的处理

    2. model负责提供数据

    3. view负责做数据的展示

    这是一种新的设计模式,不同于传统的MVC模式,MVP模式中View不直接跟Model交互,而是通过Presenter实现通信,每一层之间通过接口实现连接,这样能比较好的实现解耦。

    使用Android Studio开发这个Demo,需要添加引用:

    compile 'io.reactivex:rxjava:1.2.4'
    compile 'io.reactivex:rxandroid:1.2.1'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.okhttp3:okhttp:3.5.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    

    首先,先看一下项目的基本结构:

    首先我们看一下是Retrofit的代码:

    public interface ApiService {
        /**
         * 获取数据
         *
         * @param cityname
         * @param key
         * @return
         */
        @GET("/weather/index")
        Observable<WeatherData> getWeatherData(@Query("format") String format,
                                               @Query("cityname") String cityname,
                                               @Query("key") String key);
    
        @GET("toutiao/index")
        Observable<NewsBean> getNews(@Query("key") String key, @Query("type") String type);
    
        /**
         * 获取movie的数据
         *
         * @param start
         * @param count
         * @return
         */
        @GET("v2/movie/top250")
        Observable<MovieBean> getMovies(@Query("start") int start, @Query("count") int count);
    
    }
    

    下面是ApiServiceManager的代码:

    public class ApiServiceManager {
    
        public static Retrofit createRetrofit(String baseUrl) {
            return new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
        }
    
    
        /**
         * 获取movie,
         *
         * @param baseUrl
         * @param start
         * @param count
         * @return
         */
    
        public static Observable<MovieBean> getMovies(String baseUrl, int start, int count) {
            Retrofit retrofit = createRetrofit(baseUrl);
            ApiService apiService = retrofit.create(ApiService.class);
            Observable<MovieBean> movieBeanObservable = apiService.getMovies(start, count);
            return movieBeanObservable;
        }
    }
    

    接着是model层的代码,有一个定义一个Model的接口,然后实现这个接口:

    首先是接口的代码:

    public interface MovieModel {
    
             Subscription getMovies( int start, int count);
    }
    

    接口实现的代码:

    public class MovieModelImpl implements MovieModel {
    
        private static final String BASE_MOVIES = "https://api.douban.com/";
        private static final String TAG = "MovieModelImpl";
        private OnMoviesListener mOnMoviesListener;
    
        public MovieModelImpl(OnMoviesListener onMoviesListener) {
            this.mOnMoviesListener = onMoviesListener;
        }
    
        @Override
        public Subscription getMovies(int start, int count) {
            Observable<MovieBean> observable = ApiServiceManager.getMovies(BASE_MOVIES, start, count);
            Subscription subscribe = observable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<MovieBean>() {
                        @Override
                        public void onCompleted() {
                            Log.i(TAG, "MovieModelImpl-------->>onCompleted");
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            if (mOnMoviesListener != null) {
                                mOnMoviesListener.onFailure(e);
                            }
                        }
    
                        @Override
                        public void onNext(MovieBean movieBean) {
                            if (mOnMoviesListener != null) {
                                mOnMoviesListener.onSuccess(movieBean);
                            }
                        }
                    });
            return subscribe;
        }
    
        public interface OnMoviesListener {
            void onSuccess(MovieBean movieBean);
    
            void onFailure(Throwable throwable);
        }
    }
    

    然后是Presenter层,这一层我们定义一个BasePresenter,具体的代码是:

    public class BasePresenter {
        protected CompositeSubscription mCompositeSubscription;
    
        //RXjava取消注册,以避免内存泄露
        public void onUnsubscribe() {
            if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
                mCompositeSubscription.unsubscribe();
            }
        }
    
        //RXjava注册
        public void addSubscription(Subscription subscriber) {
            if (mCompositeSubscription == null) {
                mCompositeSubscription = new CompositeSubscription();
            }
            mCompositeSubscription.add(subscriber);
        }
    }
    

    然后是Presenter接口:

    public interface MoviePresenter {
        /**
         * @param start
         * @param count
         */
        void getMovies(int start, int count);
    
    }
    

    Presenter接口的实现

    public class MoviePresenterImpl extends BasePresenter implements MoviePresenter, MovieModelImpl.OnMoviesListener {
        private static final String TAG = "MoviePresenterImpl";
        private MovieView mMovieView;
        private MovieModel mMovieModel;
    
        public MoviePresenterImpl(MovieView movieView) {
            this.mMovieView = movieView;
            mMovieModel = new MovieModelImpl(this);
        }
    
        @Override
        public void getMovies(int start, int count) {
            mMovieView.showProgress();
            addSubscription(mMovieModel.getMovies(start, count));
        }
    
        @Override
        public void onSuccess(MovieBean movieBean) {
            mMovieView.hideProgress();
            mMovieView.getMovies(movieBean);
        }
    
        @Override
        public void onFailure(Throwable throwable) {
            mMovieView.hideProgress();
        }
    }
    

    然后是View层,这一层也设计了接口和实现:

    接口代码:

    public interface MovieView {
            void showProgress();
        
            void hideProgress();
        
        
            void getMovies(MovieBean movieBean);
    }
    

    接口的实现:

    public class MovieActivity extends AppCompatActivity implements MovieView {
        private MoviePresenter mMoviePresenter;
        private static final String TAG = "MovieActivity";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_movie);
            mMoviePresenter = new MoviePresenterImpl(this);
            mMoviePresenter.getMovies(0, 10);
        }
    
        @Override
        public void showProgress() {
    
        }
    
        @Override
        public void hideProgress() {
    
        }
    
    
        @Override
        public void getMovies(MovieBean movieBean) {
            List<MovieBean.SubjectsBean> subjects = movieBean.getSubjects();
            for (MovieBean.SubjectsBean subjectsBean:subjects) {
                Log.i(TAG,subjectsBean.getTitle());
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
        }
    }
    

    这里是简单的实现,当然有很多可以实现的封装,比如封装基本View中的方法等,这个Demo已经上传到GitHub上了,有需要的可以看一下:https://github.com/Devin1102/MvpDemo

    相关文章

      网友评论

        本文标题:Retrofit2.0+RxJava+MVP整合实践

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