Android MVP模式的简单实现

来源:互联网 发布:南京网络推广江苏斯点 编辑:程序博客网 时间:2024/05/20 12:25

MVP代码中通常包含四个元素:

  1. View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);

  2. View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;

  3. Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);

  4. Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

这里写图片描述

从图中可以看出,View已经和Model没有什么关系了,真正的逻辑在presenter中进行处理,使View和Model只依赖与Presenter,结构更加清晰

一个简单的Demo

先请求网络接口,此时View显示Loading状态,等待接口返回后,View显示真正的数据.

Loading状态
这里写图片描述

显示数据的状态
这里写图片描述

代码结构

这里写图片描述

View层

提供一个通用的View接口

/** * Created by shixi_tianrui1 on 16-12-3 * View接口需设置Presenter */public interface BaseView<T extends BasePresenter> {    void setPresenter(T presenter);}

当前Activity需实现的View接口

/** * Created by shixi_tianrui1 on 16-12-3. * View层的显示逻辑 */public interface MainView<T> extends BaseView {    void showWeatherInfo(T data);    void showProgress();    void stopProgress();    void showError();}

Model层

这里的Model层只负责准备数据,其他用Presenter进行处理

/** * Created by shixi_tianrui1 on 16-12-3. * 从网络中取{@link WeatherBean},再回调给Presenter */public class WeatherModel {    public void getWeatherData(final MyCallBack myCallBack) {        // 使用Retrofit请求数据,通过Callback对象进行回调        Call<WeatherBean> call = MyApplication.sService.getWeather("101010100");        call.enqueue(new Callback<WeatherBean>() {            @Override            public void onResponse(Response<WeatherBean> response) {                myCallBack.success(response);            }            @Override            public void onFailure(Throwable t) {                myCallBack.failure(t);            }        });    }    // 网络接口的回调    public interface MyCallBack {        void success(Response<WeatherBean> response);        void failure(Throwable throwable);    }}

Bean对象

/** * Created by shixi_tianrui1 on 16-12-3. * 网络接口返回的Bean对象 */public class WeatherBean {    private WeatherinfoBean weatherinfo;    public WeatherinfoBean getWeatherinfo() {        return weatherinfo;    }    public void setWeatherinfo(WeatherinfoBean weatherinfo) {        this.weatherinfo = weatherinfo;    }    @Override    public String toString() {        return "WeatherBean{" +                "weatherinfo=" + weatherinfo +                '}';    }    public static class WeatherinfoBean {        private String city;        private String cityid;        private String temp;        private String WD;        private String WS;        private String SD;        private String WSE;        private String time;        private String isRadar;        private String Radar;        private String njd;        private String qy;        public String getCity() {            return city;        }        public void setCity(String city) {            this.city = city;        }        public String getCityid() {            return cityid;        }        public void setCityid(String cityid) {            this.cityid = cityid;        }        public String getTemp() {            return temp;        }        public void setTemp(String temp) {            this.temp = temp;        }        public String getWD() {            return WD;        }        public void setWD(String WD) {            this.WD = WD;        }        public String getWS() {            return WS;        }        public void setWS(String WS) {            this.WS = WS;        }        public String getSD() {            return SD;        }        public void setSD(String SD) {            this.SD = SD;        }        public String getWSE() {            return WSE;        }        public void setWSE(String WSE) {            this.WSE = WSE;        }        public String getTime() {            return time;        }        public void setTime(String time) {            this.time = time;        }        public String getIsRadar() {            return isRadar;        }        public void setIsRadar(String isRadar) {            this.isRadar = isRadar;        }        public String getRadar() {            return Radar;        }        public void setRadar(String Radar) {            this.Radar = Radar;        }        public String getNjd() {            return njd;        }        public void setNjd(String njd) {            this.njd = njd;        }        public String getQy() {            return qy;        }        public void setQy(String qy) {            this.qy = qy;        }        @Override        public String toString() {            return "WeatherinfoBean{" +                    "city='" + city + '\'' +                    ", cityid='" + cityid + '\'' +                    ", temp='" + temp + '\'' +                    ", WD='" + WD + '\'' +                    ", WS='" + WS + '\'' +                    ", SD='" + SD + '\'' +                    ", WSE='" + WSE + '\'' +                    ", time='" + time + '\'' +                    ", isRadar='" + isRadar + '\'' +                    ", Radar='" + Radar + '\'' +                    ", njd='" + njd + '\'' +                    ", qy='" + qy + '\'' +                    '}';        }    }}

Presenter层

同样,提供基础接口

/** * Created by shixi_tianrui1 on 16-12-3. * Presenter基础操作 */public interface BasePresenter {    void start();}

具体业务逻辑的Presenter实现

这里持有的view和model的引用.是ui和数据的桥梁

/** * Created by shixi_tianrui1 on 16-12-3. * 对View和Model进行操作 */public class WeatherPresenter implements BasePresenter {    private Handler mHandler = new Handler();    private MainView<WeatherBean> mView;    private WeatherModel mModel;    public WeatherPresenter(MainView<WeatherBean> view) {        this.mView = view;        mModel = new WeatherModel();    }    private void getHttpData() {        mModel.getWeatherData(new WeatherModel.MyCallBack() {            @Override            public void success(Response<WeatherBean> response) {                mView.stopProgress();                mView.showWeatherInfo(response.body());            }            @Override            public void failure(Throwable throwable) {                mView.stopProgress();                mView.showError();            }        });    }    @Override    public void start() {        mView.showProgress();        // 模拟网络延时        mHandler.postDelayed(new Runnable() {            @Override            public void run() {                getHttpData();            }        }, 10000);    }}

Activity中的只需实现View接口即可,并且将自身设置给Presenter

可以看出,实现的都是View接口的方法

/** * Activity是MainView的具体实现 */public class MainActivity extends AppCompatActivity implements MainView<WeatherBean> {    private WeatherPresenter mPreserter = new WeatherPresenter(this);    private TextView mTvText;    private View mLoading;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mTvText = (TextView) findViewById(R.id.id_tv_text);        mLoading = findViewById(R.id.id_fl_loading);        // Presenter进行处理        mPreserter.start();    }    @Override    public void showWeatherInfo(WeatherBean data) {        mTvText.setText(data.toString());    }    @Override    public void showProgress() {        mLoading.setVisibility(View.VISIBLE);    }    @Override    public void stopProgress() {        mLoading.setVisibility(View.GONE);    }    @Override    public void showError() {        mTvText.setText("network error!");    }    @Override    public void setPresenter(BasePresenter presenter) {        mPreserter = (WeatherPresenter) presenter;    }}

Retroft请求类

Retroft初始化

public class MyApplication extends Application {    public static ApiService sService;    @Override    public void onCreate() {        super.onCreate();        // 初始化Retrofit        File httpCacheDirectory = new File(getExternalCacheDir(), "responses");        Cache cache = new Cache(httpCacheDirectory, 20 * 1024 * 1024);        OkHttpClient client = new OkHttpClient.Builder()                .cache(cache).build();        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://www.weather.com.cn/")                .client(client)                .addConverterFactory(GsonConverterFactory.create())                .build();        sService = retrofit.create(ApiService.class);    }}

Api请求

public interface ApiService {    @GET("adat/sk/{cityId}.html")    Call<WeatherBean> getWeather(@Path("cityId") String cityId);}
0 0
原创粉丝点击