前言
2016年的尾声mvp+rxjava+retrofit这套框架。可以说是风靡,但是当时的我只是在其他大神的博客中看看,没有深入了解,原因也是当时项目着急,没有精力去学习,2017年初,公司运营不善,换了新工作,0到1的项目,也使我有了实战这套风靡的框架。。。
我先说我搭建封装的结构后面有解析
关键类贴出:
public abstract class BasePresenterImpl<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> {
protected T mView;
protected CompositeSubscription mCompositeDisposable;
protected CompositeSubscription RxBusSubscriptions;
protected ApiStores apiStores;
@Override
public void attachView(T view) {
mView = view;
apiStores = AppClient.retrofit().create(ApiStores.class); //retrofit初始化
mCompositeDisposable = new CompositeSubscription();
RxBusSubscriptions = new CompositeSubscription();
attachView();
}
@Override
public void detachView() {
mCompositeDisposable.unsubscribe();
RxBusSubscriptions.clear();
RxBusSubscriptions.unsubscribe();
}
protected abstract void attachView();
protected T getView() {
return mView;
}
protected CompositeSubscription getSubscription() {
return mCompositeDisposable;
}
@Override
public void subscribe() {
}
@Override
public void unsubscribe() {
mCompositeDisposable.clear();
}
public void addSubscription(Observable observable, Subscriber subscriber) {
if (mCompositeDisposable == null) {
mCompositeDisposable = new CompositeSubscription();
}
mCompositeDisposable.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber));
}
}
Presenter控制逻辑,也就是控制网络操作,绑定数据,一系列逻辑都在这.
那么,当activity关闭以后,Presenter怎么处理网络请求,异步操作呢?
比如上面的loadData(),如果acitivity已经关闭了,而网络操作又没走完.
就会内存泄漏.会不会空指针不好说.
view虽然持有p,但是也不能在Activity的onDestroy里面直接的将p=null吧
对象=null也只是断开引用而已,还并不是真的释放.
这样没用的,而且p还持有view呢,异步也不会因此结束,
所以得有个接口告诉p,我要挂了,你也自杀吧.
所以:
interface BasePresenter {
void onStart();
void onDestroy();
}
让所有的Presenter都继承BasePresenter,然后在activity中相应的生命周期里面调用
在相应的方法里面,初始化,结束异步操作,释放资源,将view=null;
而在activity里面,由于Presenter并没有view的引用了,
所以p随着activity的销毁也就跟着销毁了.不会造成上下文的泄漏等.
正确代码:
public interface BasePresenter<T extends BaseView> {
void attachView(T view);
void detachView();
void subscribe();
void unsubscribe();
}
在BaseActiuvity生命周期
@Override
protected void onResume() {
super.onResume();
mPresenter.subscribe();
}
@Override
protected void onStop() {
super.onStop();
mPresenter.unsubscribe();
}
@Override
protected void onDestroy() {
super.onDestroy();
mPresenter.detachView();
}
MVP设计模式
不算是个新鲜的东西了,大概解读下:
M层 : model 模型.
也可以理解成bean对象,我觉得不全是, 用获取数据比较贴切.
在以前写mvc的时候,我习惯抽成initData()来表示modle.
public interface Model {
Bean load(String url,params)
}
modle,我推荐用retrofit2+rxjava来写,完全适用啊,对比一看,是不是感觉几乎没区别?
V层:view视图
在mvp中,有人把activity/fragment理解成presenter,
我觉得还是理解成v好一点,
比较纠结是,activity有生命周期,怎么就是单纯的v呢.
但如果理解成presenter的话,那么和mvc区别就不大了吧.
具体使用:
1.写一个view接口
public interface View {
//抽取相对的activity里面的各种行为
//如:
void show();
void bindData(Bean b);
}
2,activity实现这个设计好的view接口
public class MainActivity extends Activity implements View{
Presenter presenter;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter = new Presenter(this);
}
public void show(){
}
public void bindData(Bean b){
........
//等待数据,设置view.
}
}
3,实现每个行为的逻辑:对某个控件做什么事.
public void show(){
//具体操作.比如弹个toast啥的,设置某个控件啥的
}
4.持有presenter
这里有点难理解,持有presenter是什么意思?
我们不管做什么操作,都是一次事件
而这个事件由谁接收,当然是activity接收了.
如果activity不持有presenter,怎么告诉presenter,我需要获得数据.
p:控制 presenter
一般写法:
public interface Presenter {
void loadData();
}
public interface PresenterImpl implements Presenter {
View v;
public PresenterImpl(View v){
this.v = v;
}
publc void loadData(){
Modler modle = new Modle();//创建modle
Bean bean = modle.load("url",params);//获得数据
v.bindData(bean);//数据绑定view
}
}
总结:
presenter和view相互持有调用,presenter可以同时操作Modle和View,但是Modle和View之间不能调用.
Retrifit
它的作用介绍我就不多废话。
重点
public class AppClient {
private static final String TAG = "AppClient";
public static Retrofit mRetrofit;
public static Retrofit retrofit() {
if (mRetrofit == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
// Log信息拦截器
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Logger.t(TAG).i(message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(logging);
}
OkHttpClient okHttpClient = builder.build();
okHttpClient.networkInterceptors();
okHttpClient.connectTimeoutMillis();
mRetrofit = new Retrofit.Builder()
.baseUrl(AppNetConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
}
return mRetrofit;
}
}
在baseactivty中初始化Presenter,接下来就是在basePresenter中初始化Retrofit了
源代码如下:别忘记在结束时取消订阅
public abstract class BasePresenterImpl<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> {
protected T mView;
protected CompositeSubscription mCompositeDisposable;
protected CompositeSubscription RxBusSubscriptions;
protected ApiStores apiStores;
@Override
public void attachView(T view) {
mView = view;
apiStores = AppClient.retrofit().create(ApiStores.class); //retrofit初始化
mCompositeDisposable = new CompositeSubscription();
RxBusSubscriptions = new CompositeSubscription();
attachView();
}
@Override
public void detachView() {
mCompositeDisposable.unsubscribe();
RxBusSubscriptions.clear();
RxBusSubscriptions.unsubscribe();
}
protected abstract void attachView();
protected T getView() {
return mView;
}
protected CompositeSubscription getSubscription() {
return mCompositeDisposable;
}
@Override
public void subscribe() {
}
@Override
public void unsubscribe() {
mCompositeDisposable.clear();
}
public void addSubscription(Observable observable, Subscriber subscriber) {
if (mCompositeDisposable == null) {
mCompositeDisposable = new CompositeSubscription();
}
mCompositeDisposable.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber));
}
}
总结:实战中可以先简单的搭建,一点一滴的完善你的框架希望对你有所帮组。大神轻喷(一个顺手的框架史书很重要哦)有不懂的同学可以加我qq咨询425043853,答案随便写。