Android——MVP+Retrofit2.0+RxJava框架整合

对三者的学习已经有一段时间了,现在写了一个基础版本的整合Demo,因为下个项目就要正式开始了,这段时间会不断对该Demo进行扩展补充。

Demo的Github地址:https://github.com/jiangzhengnan/SimpleMvpRxJavaRetrofit

下面是运行截图:


首先让我们回顾一下各部分的原理:

MVP模式结构

  • Model: 业务逻辑和实体模型
  • View:用户交互和视图显示,在android中对应activity
  • Presenter: 负责完成View于Model间的逻辑和交互


Retrofit2.0

这里贴上一篇不错的文章:Retrofit 2.0: The biggest update yet on the best HTTP Client Library for Android

RxJava

各种调用以及使用场景可以点这里:RxJava使用场景总结


下面开始讲解本项目的整体构造:

包结构:


感觉这样分包还是比较适合个人开发,我可能在后期会进行改进,团队开发还是用功能进行分包更加好区分。

设计原则:
在MVP三层互相的基础之上,对各层的逻辑设计采用依赖倒置原则,即具体实现依赖于抽象,便于未来功能拓展。
以Presenter层为例:


IPresenter为最上层接口,包含最基本的onUnsubscribe()和addSubscription()实现抽象方法对Subscription的管理防止内存泄漏。
IBookPresenter为二级接口,在继承IPresenter的基础上包含自己的getBookInfo(String isbn)获取天气信息方法。
BasePresenter为标准Presenter类,包含一个CompositeSubscription实例并实现了onUnsubscribe()和addSubscription()方法。
BooKPresenter继承自BasePresenter并实现了IBookPresenter,可根据模块需求随上层模块结构变动变化。

代码实现:
因为代码量比较多,所以不会贴出全部代码,只展示一部分具有代表性的,具体的工程可以去文章开头的Github上下载。
View层:
package com.jzn.simplemvprxjavaretrofit;

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.widget.TextView;
import com.jzn.simplemvprxjavaretrofit.common.BaseActivity;
import com.jzn.simplemvprxjavaretrofit.presenter.BookPresenter;
import com.jzn.simplemvprxjavaretrofit.utils.LogUtils;
import com.jzn.simplemvprxjavaretrofit.utils.ToastUtils;
import com.jzn.simplemvprxjavaretrofit.view.IBookView;
import org.json.JSONException;
import org.json.JSONObject;
import butterknife.Bind;
import butterknife.ButterKnife;

public class BookActivity extends BaseActivity implements IBookView {
    @Bind(R.id.tv_title_bookdetail)
    TextView tv_title_bookdetail;
    @Bind(R.id.tv_autor_bookdetail)
    TextView tv_autor_bookdetail;
    @Bind(R.id.tv_price_bookdetail)
    TextView tv_price_bookdetail;
    @Bind(R.id.tv_pages_bookdetail)
    TextView tv_pages_bookdetail;

    @Bind(R.id.tv_detail_bookdetail)
    TextView tv_detail_bookdetail;

    private BookPresenter mBookPresenter;
    @Bind(R.id.refresh_layout_main)
    SwipeRefreshLayout srl;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        init();
        //获取数据
        mBookPresenter = new BookPresenter(this);
        mBookPresenter.getBookInfo("isbn/:9787121267734");
    }

    @Override
    public void init() {
        srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mBookPresenter = new BookPresenter(BookActivity.this);
                mBookPresenter.getBookInfo("isbn/:9787121267734");
            }
        });
    }

    @Override
    public void showProgress() {
        setLoadingIndicator(true);
    }

    @Override
    public void hideProgress() {
        mBookPresenter.onUnsubscribe();
        setLoadingIndicator(false);

    }

    @Override
    public void loadBookInfo(String bookInfo) {
        LogUtils.d("BookInfo==" + bookInfo.toString());
        try {
            JSONObject jsonObject = new JSONObject(bookInfo);
            tv_title_bookdetail.setText(jsonObject.getString("title"));
            tv_autor_bookdetail.setText(jsonObject.getString("author"));
            tv_price_bookdetail.setText(jsonObject.getString("price"));
            tv_pages_bookdetail.setText(jsonObject.getString("pages"));
            tv_detail_bookdetail.setText(jsonObject.getString("summary"));
        } catch (JSONException e) {
            LogUtils.d(e.getMessage());
            e.printStackTrace();
        }


    }

    @Override
    public void setLoadingIndicator(final boolean active) {
        srl.post(new Runnable() {
            @Override
            public void run() {
                //显示刷新框
                srl.setRefreshing(active);
            }
        });
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册
        mBookPresenter.onUnsubscribe();
    }
}
可以看到View层没有任何数据相关代码,全是视图层代码。

api层:
BookInfoManagerService接口:
public interface BookInfoManagerService {
    //https://api.douban.com/v2/book/isbn/:9787121267734
    @GET("v2/book/{isbn}")
    Observable<String> getBookInfo(@Path("isbn") String isbn);
}
BookInfoManager:
/**
 * 使用Retrofit获取图书信息
 * Created by jiangzn on 16/9/27.
 */
public class BookInfoManager {
    private static final Retrofit sRetrofit = new Retrofit.Builder()
            .baseUrl(Config.QUERY_PATH)
            //增加返回值为String的支持
            .addConverterFactory(ScalarsConverterFactory.create())
            //增加返回值为Gson的支持(以实体类返回)
            .addConverterFactory(GsonConverterFactory.create())
            //增加返回值为Oservable<T>的支持
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

    private static final BookInfoManagerService mManager = sRetrofit.create(BookInfoManagerService.class);

    public static Observable<String> getBookInfo(String isbn) {
        return mManager.getBookInfo(isbn);
    }

}

model层:
/**
 * Created by jiangzn on 16/9/27.
 */
public class BookModel implements IBookModel {
    private BookOnListener mBookOnListener;

    public BookModel(BookOnListener mBookOnListener) {
        this.mBookOnListener = mBookOnListener;
    }

    @Override
    public Subscription getBookData(String isbn) {
        Observable<String> request = BookInfoManager.getBookInfo(isbn);
        Subscription sub = request.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                               @Override
                               public void call(String s) {
                                mBookOnListener.onSuccess(s);
                               }
                           },
                        new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                mBookOnListener.onFailure(throwable);
                            }
                        });
        return sub;
    }

    /**
     * 请求结果回调接口
     */
    public interface BookOnListener {
        void onSuccess(String s);

        void onFailure(Throwable e);
    }
}
这里通过回调进行数据请求结果通知。

Presenter层:
/**
 * Created by jiangzn on 16/9/27.
 */
public class BookPresenter extends BasePresenter implements IBookPresenter,BookModel.BookOnListener {
    private IBookModel mBookModel;
    private IBookView mBookView;

    public BookPresenter(IBookView mBookView) {
        this.mBookView = mBookView;
        this.mBookModel = new BookModel(this);
    }

    @Override
    public void getBookInfo(String isbn) {
        mBookView.showProgress();
        addSubscription(mBookModel.getBookData(isbn));
    }


    @Override
    public void onSuccess(String s) {

    }

    @Override
    public void onFailure(Throwable e) {
        mBookView.hideProgress();
        LogUtils.d("onFailure() :" + e.getMessage());
    }
}
可以看到所有的逻辑交互都集中在Presenter层,跟视图层实现基本解耦。


之后的时间会在此基础上不断完善,其实现在的代码中还是存在很多弊病,比如内存泄漏,以及不利于模块化开发等等等等。
Github会持续更新,欢迎Start欢迎watch~





  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值