mvp+rxjava+rxbus+retrofit+butter

作者: 茴香豆的第五种写法 | 来源:发表于2017-04-18 13:31 被阅读0次

    mvp+rxjava+rxbus+retrofit+butterknife最新实践

    了解android的人应该经常听到一些框架术语,比如说mvc,mvp, mvvp ,rxjava,rxandroid等等,最近有时间所以整理了一些基本的demo,下面我们来具体看看.

    mvp:相对于mvc来说将view和model分离开来,由persenter控制,这样有利于代码解耦和,如果业务新增需求,则只需要改动model,不需要改动view层,下面看下目录结构和需要引用的jar

    首先定义一个接口model,里面包含了需要做的method,

    void setUserName(String username);

    void setPwd(String pwd);

    UserBean load(int id);//通过id读取user信息,返回一个

    UserBean    Listsave(int id, String username, String pwd);//通过id保存user信息,返回一个UserBean

    然后写一个model实现类,实现类中接受presenter传过来的值或者方法,

    @Override

    public Listsave(intid,String username,String pwd) {

    UserBean userBean =newUserBean(id,username,pwd);

    userBeens.add(userBean);

    returnuserBeens;

    }

    然后定义一个view接口

    StringgetUserName();

    StringgetPwd();

    voidsetUserName(StringuserName);

    voidsetPwd(Stringpwd);

    之后在定义一个persenter类,这里persenter管理着view 和model两个实现类,

    public classUserPresenter {

    privateIUserViewmUserView;

    privateIUserModelmUserModel;

    publicUserPresenter(IUserView mUserView) {

    this.mUserView= mUserView;

    this.mUserModel=newIUserModelimpl();

    }

    public voidsaveUser(intid,String username,String pwd) {

    mUserModel.setId(id);

    mUserModel.setUserName(username);

    mUserModel.setPwd(pwd);

    mUserModel.save(id,username,pwd);

    }

    public voidloadUser(intid) {

    UserBean bean =mUserModel.load(id);

    mUserView.setUserName(bean.getName());//通过调用IUserView的方法来更新显示

    mUserView.setPwd(bean.getPwd());

    }

    之后就是我们自己的activity里面了或者fragment里面了,我们需要实现view接口,在view实现类中new 一个presenter对象,然后在执行方法时候调用

    presenter.saveUser(getID(),getUserName(),getPwd());

    presenter.loading(MainActivity.this);

    如果需要新增一个方法,比如加载一个loading ,我们可以直接在presenter中添加

    public voidloading(Context context) {

    finalProgressDialog dialog = ProgressDialog.show(context,"登录中...","正在登录...");

    newThread(newRunnable() {

    @Override

    public voidrun() {

    try{

    Thread.sleep(2000);

    dialog.cancel();

    }catch(InterruptedException e) {

    e.printStackTrace();

    }

    }

    }).start();

    }

    这样确实比较方便,拓展性也比较强.总结一些mvp就是说我们的presenter完成二者的交互,那么肯定需要二者的实现类。大致就是从View中获取需要的参数,交给Model去执行业务方法,执行的过程中需要的反馈,以及结果,再让View进行做对应的显示。

    rxjava异步任务其主要的核心就是观察者模式,以前的文章中有专门说过观察者,通过observer观察者和observerble被观察者进行的订阅事件,这里来说的是用Retrofit+rxjava一起使用.Retrofit是一个底层由okhttp封装的网络请求框架,可以取消单个网络请求,主要使用配置如下:

    OkHttpClient.Builder httpclientBuilder =newOkHttpClient.Builder();

    httpclientBuilder.connectTimeout(DEFAULT_TIMEOUT,TimeUnit.SECONDS);

    retrofit=newRetrofit.Builder()

    .client(httpclientBuilder.build())

    .addConverterFactory(GsonConverterFactory.create())

    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())

    .baseUrl(baseUrl)

    .build();

    movieService=retrofit.create(MovieService.class);

    addCallAdapterFactory可以添加对rxjava的支持,也就是说原有的retrofit在请求成功后用Call来回调,这里如果用rxjava的话,就是Subscriber来进行回调处理.

    原生的请求方式:

    @GET("top250")

    CallgetTopMovie(@Query("start")intstart,@Query("count")intcount);

    rxjava请求方式:

    @GET("top250")

    ObservablegetTopMoviebyRx(@Query("start")intstart,@Query("count")intcount);

    配置MovieService时候可以用到

    在bean中建立右键找到GsonFormat

    粘贴json文件就可以一次性生成方法.如MovieBean

    继续来说retrofit使用

    public voidgetTopMovie(Subscriber subscriber, intstart, intcount) {

    movieService.getTopMoviebyRx(start,count)

    .subscribeOn(Schedulers.io())

    .unsubscribeOn(Schedulers.io())

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(subscriber);

    }

    定义一个观察者,执行请求时候调用:

    private voidgetMovieByRx() {

    subscriber=newSubscriber() {

    @Override

    public voidonCompleted() {

    Toast.makeText(RetrofitActivity.this,"Get Top Movie Completed",Toast.LENGTH_SHORT).show();

    }

    @Override

    public voidonError(Throwable e) {

    //subscriber.unsubscribe();//取消一个网络请求

    Toast.makeText(RetrofitActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();

    }

    @Override

    public voidonNext(MovieBean movieBean) {

    Log.e("content",movieBean.getTitle());

    }

    };

    BaseUrl.getInstance().getTopMovie(subscriber,0,10);

    }

    onComplete网络请求结束;onError请求失败,onEext获取请求结果,这里观察者是没有unrester方法的,如果需要取消网络请求可以用subscrrber的unsubcrible来取消订阅就可以取消网络请求.

    Butterknife注解,可以方便xml中生成id属性的定义,

    下载好后重启as,然后

    右键选择需要生成的id和是否生成关联的onclick点击事件,生成好后就是

    @Bind(R.id.retrofit)

    Buttonretrofit;

    @Bind(R.id.retrofitrx)

    Buttonretrofitrx;

    @Bind(R.id.rxbus)

    Buttonrxbus;

    onclick方法中:

    @OnClick({R.id.retrofit,R.id.retrofitrx,R.id.rxbus})

    public voidonViewClicked(View view) {

    switch(view.getId()) {

    caseR.id.retrofit:

    break;

    caseR.id.retrofitrx:

    getMovieByRx();

    break;

    caseR.id.rxbus:

    RxBus.getInstance().post(newRefreshMessage("mingzi","333"));

    break;

    }

    现在在来说说rxbus这个的使用 方法,以前经常用的是eventBus,里面有一个otto.jar,但是在引入了rxjava和rxandroid.jar后,去执行otto方法时候Bus.getInstance.post(new Method(params))时候,执行就会报错,而且接收方@subscribe方法也监听不到,既然这样,那就使用rxbus看看是否可以,与eventbus使用方法大同小异,目的就是在当前代码中执行任何一个地方的方法,使用如下:

    定一个基类,说明发送消息和接收消息等方法

    public classRxBus {

    private static volatileRxBusmInstance;

    private finalSubjectbus;

    publicRxBus() {

    bus=newSerializedSubject<>(PublishSubject.create());

    }

    /**

    *单例模式RxBus

    *

    *@return

    */

    public staticRxBusgetInstance() {

    RxBus rxBus2 =mInstance;

    if(mInstance==null) {

    synchronized(RxBus.class) {

    rxBus2 =mInstance;

    if(mInstance==null) {

    rxBus2 =newRxBus();

    mInstance= rxBus2;

    }

    }

    }

    returnrxBus2;

    }

    /**

    *发送消息

    *

    *@paramobject

    */

    public voidpost(Object object) {

    bus.onNext(object);

    }

    /**

    *接收消息

    *

    *@parameventType

    *@param

    *@return

    */

    public ObservabletoObserverable(Class eventType) {

    returnbus.ofType(eventType);

    }

    然后定义我们需要传递的参数,这里可以什么也不传,也可以传递对象

    public classRefreshMessage {

    privateStringname;

    privateStringid;

    publicRefreshMessage(String name,String id) {

    this.name= name;

    this.id= id;

    }

    publicStringgetName() {

    returnname;

    }

    public voidsetName(String name) {

    this.name= name;

    }

    publicStringgetId() {

    returnid;

    }

    public voidsetId(String id) {

    this.id= id;

    }

    }

    执行发送方法:

    RxBus.getInstance().post(newRefreshMessage("mingzi","333"));

    然后在需要接收的类里面接收方法,activity中可以写在onCreate或者onStart中:

    rxbus= RxBus.getInstance().toObserverable(RefreshMessage.class)

    .subscribe(newAction1() {

    @Override

    public voidcall(RefreshMessage refreshMessage) {

    Toast.makeText(MainActivity.this,refreshMessage.getName() + refreshMessage.getId(),Toast.LENGTH_LONG).show();

    }

    });

    为了避免oom问题,在onDestroy中解除订阅

    @Override

    protected voidonDestroy() {

    if(!rxbus.isUnsubscribed()) {

    rxbus.unsubscribe();

    }

    super.onDestroy();

    }

    这里附上源码地址,欢迎star,fork,后续继续更新中...

    相关文章

      网友评论

        本文标题:mvp+rxjava+rxbus+retrofit+butter

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