MVP+RxJava2+Retrofit2应用在项目的记录

这几天学了一下子Android中常用的框架,感觉还是迷迷糊糊的先记录一下吧。

MVP架构是由Model、Presenter、View这三个组成。

Model表示模型,主要负责数据的加载;VIew表示视图主要负责视图绑定,界面的展示,界面逻辑跳转等;Presenter是表示器,主要作为View和Model的中间人,完成他们之间的交互,从而实现高内聚低耦合的思想。
下图是偷的B站大佬的视频截图(QAQ...)大概就是把数据获取和展示分开来做,使得代码结构清晰,易于维护。

MVP+RxJava2+Retrofit2应用在项目的记录_第1张图片

但是一般实际项目中会在建立一个Contract,这又是什么鬼?
这就涉及到MVP的缺点了,正所谓,金无足赤,人无完人,MVP既然有优点当然也有它的缺点了
MVP在实现代码简洁的同时,额外增加了大量的接口、类,不方便进行管理,于是Contract就登场了。

Contract 百度翻译 : 合同;契约;协议
Contract 如其名,是一个契约,将Model、View、Presenter 进行约束管理,方便后期类的查找、维护。

基于MVP这个思想可以有很多的实现方式,上面展示的这个方式是Google官方提出的一种MVP实现方式。谷歌官方的MVP实现方式中,弱化了Model的作用,将Model融入到了Presenter中。本套代码也是仿照了Google的方式实现的(弱弱的小白虽然不懂,毕竟得抱紧大佬的腿嘛。。。)

以下代码来自大佬的Github,仰望。。。只是粘了比较重要的部分

代码结构:

MVP+RxJava2+Retrofit2应用在项目的记录_第2张图片

MVP的结构是  MainActivity、MainContract、MainPresenter

MainContract:定义了接口规范

MainPresenter:具体代码逻辑的实现

 

MainActivity:

package com.chaochaow.weather;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.loopeer.cardstack.CardStackView;
import com.loopeer.cardstack.UpDownAnimatorAdapter;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity implements MainContract.View, CardStackView.ItemExpendListener {

    MainPresenter presenter;
    @BindView(R.id.stackview_main)  //绑定控件 减少findviewbyId的使用
    CardStackView mStackview;
    WeatherStackAdapter mAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //隐藏隐藏上面的ActionBar
        getSupportActionBar().hide();

        //设置窗体全屏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);  //绑定控件

        //MVP架构
        presenter = new MainPresenter(this);

        String[] cities = new String[]{"青岛", "绍兴", "成都", "武汉", "重庆", "南京", "天津", "苏州", "西安", "长沙", "沈阳",
                 "郑州", "大连", "宁波", "厦门", "福州", "无锡", "合肥", "昆明", "哈尔滨", "济南", "佛山", "长春", "温州"};

        //从服务器获取天气数据 并且 调用setData实现UI更新
        presenter.getData(cities);

    }

    @Override
    public void setData(List weatherEntities) {

        mAdapter = new WeatherStackAdapter(this);
        mStackview.setAnimatorAdapter(new UpDownAnimatorAdapter(mStackview));
        mStackview.setItemExpendListener(this);
        mAdapter.setData(weatherEntities);
        mStackview.setAdapter(mAdapter);

    }

    @Override
    public void dataError(Throwable e) {
        Toast.makeText(this,"加载失败...",Toast.LENGTH_LONG).show();
    }

    @Override
    public void onItemExpend(boolean expend) {

    }

}

MainContract: 

package com.chaochaow.weather;

import java.util.List;


public interface MainContract {

    interface View{
        /**
         * presenter获取数据后调用此方法将数据展示到界面上
         * @param weatherEntities 获取到的天气数据
         */
        void setData(List weatherEntities);

        /**
         * presenter获取数据失败调用此方法将错误信息展示到界面上
         * @param e
         */
        void dataError(Throwable e);
    }

    interface Presenter{
        /**
         * 从服务器获取天气数据
         */
        void getData(String[] cities);
    }

}

MainPresenter:RxJava2+Retrofit2网络请求部分

package com.chaochaow.weather;

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @author chaochaowu
 * @Description : MVP框架中的presenter用来处理数据请求
 * @class : MainPresenter
 * @time Create at 5/28/2018 2:05 PM
 */


public class MainPresenter implements MainContract.Presenter{

    MainContract.View mView;

    public MainPresenter(MainContract.View mView) {
        this.mView = mView;
    }

    @Override
    public void getData(String[] cities) {

        final List weatherEntities = new ArrayList<>();

        Retrofit retrofit = new Retrofit.Builder()   //网络请求
                .baseUrl("https://free-api.heweather.com")  //一个baseurl地址,网络请求的接口地址
                .addConverterFactory(GsonConverterFactory.create()) //设置数据解析的工具。geson
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                /*让retrofit返回一个Observable类型,用于之后rxjava相关操作。*/
                .build();

        WeatherService weatherService = retrofit.create(WeatherService.class);

        for (String city : cities) {

            weatherService.getWeather("0adc843380064d1c9c11ddf49de8----", city)
                    .subscribeOn(Schedulers.io())//subscribeOn方法声明请求是在io线程上执行
                    .observeOn(AndroidSchedulers.mainThread())//ObserveOn声明回调的操作是在UI线程上执行
                    .subscribe(new Observer() {//subscribe里定义的便是请求之后的操作
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(WeatherEntity weatherEntity) {
                            weatherEntities.add(weatherEntity);
                        }

                        @Override
                        public void onError(Throwable e) {
                            mView.dataError(e);
                        }

                        @Override
                        public void onComplete() {
                            mView.setData(weatherEntities);
                        }
                    });

        }


    }
}

WeatherService :retrofit2框架定义请求格式,根据要请求地址的API

package com.chaochaow.weather;


import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;


public interface WeatherService {

    /**
     * 获取指定城市的天气信息
     * @param key 开发者key
     * @param location 城市名称
     * @return 返回一个Observable类型 用于Rxjava的处理
     */
    @GET("s6/weather/now")
    Observable getWeather(@Query("key") String key, @Query("location") String location);

}

 

你可能感兴趣的:(Android)