LookLook剖析,架构概述——MVP、Retrofit+RxJava

前言:
学习LookLook这个开源项目的初衷是学习MVP架构,因为自己已经块学了一年的Android,可是对架构一直没有什么概念,而且平时自己编项目时总是没有框架。写到哪里,就封装到哪里,照着一些接口自己总是瞎写写,收获甚微,代码乱,所以出现最多的情况就是写不下去了,代码不仅没法扩展,也没法修改。

项目地址:https://github.com/xinghongfei/LookLook

LookLook的最大特点就是他的MVP架构,所以让我们先从MVP架构看起:
MVP:Model、View、Presenter
简单来说就是将应用分为三层,降低耦合性:数据(Bean)、视图(Activity、Fragment)、适配器,并且View和Model分别与Presenter交互,View和Model不交互
哈哈,怎么听着这么像AdapterView呢(悄悄告诉你,RecyclerView的适配器里也有观察者模式的踪影哦)!

让我们来看一下LookLook:
^_^
ps:初学UML,图画的不标准,还请见谅!!!

我们可以先构想一下数据刷新的整个过程:
用户触发加载刷新等操作 –> View通知Presenter更新数据 –> Presenter通知Model获取数据 –> 加载完毕 –> Model 通知Presenter数据发生改变 –> Presenter通知View更新界面

View和Presenter的交互:
View持有Presenter的引用,当用户触发加载操作的时候,调用Presenter的getData()方法通知数据更新。
当数据更新完成后,presenter会在内部拿着View的引用来进行UI操作(updateMeiziData()…)。

Model和Presenter的交互方式很特殊,采用了RxJava+Retrofit的方式:
上代码:

public interface ZhihuApi {

    @GET("/api/4/news/latest")
    Observable<ZhihuDaily> getLastDaily();

    @GET("/api/4/news/before/{date}")
    Observable<ZhihuDaily> getTheDaily(@Path("date") String date);

    @GET("/api/4/news/{id}")
    Observable<ZhihuStory> getZhihuStory(@Path("id") String id);
}

ApiManager:这里我只贴部分代码

public class ApiManage {
    public ZhihuApi getZhihuApiService() {
        if (zhihuApi == null) {
            synchronized (zhihuMonitor) {
                if (zhihuApi == null) {
                    zhihuApi = new Retrofit.Builder()
                            .baseUrl("http://news-at.zhihu.com")
                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                            // 注意这里添加RxJavaCallAdapterFactory
                            .client(client)
                            .addConverterFactory(GsonConverterFactory.create())
                            .build().create(ZhihuApi.class);
                }
            }
        }
        return zhihuApi;
    }
}

这样通过这个方法就可以获得RxJava的被观察者了,然后只要在Presenter中向这个被观察者中添加几个随从(观察着),就可以随时获悉数据的变化情况

public class ZhihuPresenterImpl extends BasePresenterImpl implements IZhihuPresenter {

    // presenter持有view的引用
    private IZhihuFragment mZhihuFragment;
    private CacheUtil mCacheUtil;
    private Gson gson = new Gson();

    public ZhihuPresenterImpl(Context context,IZhihuFragment zhihuFragment) {

        mZhihuFragment = zhihuFragment;
        mCacheUtil = CacheUtil.get(context);
    }

    @Override
    public void getLastZhihuNews() {
        mZhihuFragment.showProgressDialog();
        Subscription subscription = ApiManage.getInstance().getZhihuApiService().getLastDaily()
                .map(new Func1<ZhihuDaily, ZhihuDaily>() { //添加了观察者,当这些观察者发现数据状态有变时,就会使用View的接口来更新UI
                    @Override
                    public ZhihuDaily call(ZhihuDaily zhihuDaily) {
                        String date = zhihuDaily.getDate();
                        for (ZhihuDailyItem zhihuDailyItem : zhihuDaily.getStories()) {
                            zhihuDailyItem.setDate(date);
                        }
                        return zhihuDaily;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ZhihuDaily>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        mZhihuFragment.hidProgressDialog();
                        mZhihuFragment.showError(e.getMessage());
                    }

                    @Override
                    public void onNext(ZhihuDaily zhihuDaily) {
                        mZhihuFragment.hidProgressDialog();
                        mCacheUtil.put(Config.ZHIHU, gson.toJson(zhihuDaily));
                        mZhihuFragment.updateList(zhihuDaily);
                    }
                });
        addSubscription(subscription);
    }

    @Override
    public void getTheDaily(String date) {
        Subscription subscription = ApiManage.getInstance().getZhihuApiService().getTheDaily(date)
                .map(new Func1<ZhihuDaily, ZhihuDaily>() {
                    @Override
                    public ZhihuDaily call(ZhihuDaily zhihuDaily) {
                        String date = zhihuDaily.getDate();
                        for (ZhihuDailyItem zhihuDailyItem : zhihuDaily.getStories()) {
                            zhihuDailyItem.setDate(date);
                        }
                        return zhihuDaily;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ZhihuDaily>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        mZhihuFragment.hidProgressDialog();
                        mZhihuFragment.showError(e.getMessage());
                    }

                    @Override
                    public void onNext(ZhihuDaily zhihuDaily) {
                        mZhihuFragment.hidProgressDialog();
                        mZhihuFragment.updateList(zhihuDaily);
                    }
                });
        addSubscription(subscription);
    }

    @Override
    public void getLastFromCache() {
        if (mCacheUtil.getAsJSONObject(Config.ZHIHU) != null) {
            ZhihuDaily zhihuDaily = gson.fromJson(mCacheUtil.getAsJSONObject(Config.ZHIHU).toString(), ZhihuDaily.class);
            mZhihuFragment.updateList(zhihuDaily);
        }
    }
}

是不是很简单呢?MVP也基本就是这个样子,很有利于后期的维护和代码的修改,至少思路还是很清晰的!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值