前言
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,答案隨便寫。