Android MVP模式的简单实现

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);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值