所謂MVP(Model-View-Presenter)模式。是將APP的結構分爲三層:java
view 層主要負責:android
注意. View層不存儲數據,不與Model層交互。git
presenter 層主要負責:github
model層主要負責:面試
如圖示,裏面的activity,presenter,model均爲例子:
數據庫
**mvp**
將複雜的功能分割爲各層內的小問題。各層內功能單一。這樣易於功能修改拓展與Debug。
解耦的設計,獨立的模塊,更有利於分工開發與測試。
Activity的異常重啓性能優化
當用戶旋轉屏幕 在後臺時內存不足 改變語言設置 attache 一個外部顯示器等。
正確的方式應該是:
Presenter與Activity的綁定關係應由靜態類管理。而不是由Activity管理。當Activity意外重啓時Presenter不該重啓。Activity重啓時,Presenter與Activity從新綁定,根據數據恢復Activity狀態。
而當Activity真正銷燬時。對應Presenter才應該跟隨銷燬。
當內存不足時,Activity被銷燬實際上是整個進程被銷燬。因此Presenter也無能爲力。還原時須要重建Presenter。服務器
Activity是一個上帝類,其實不適合做爲View。因此有些MVP方案將Activity做爲Presenter。最主要在於他的生命週期牽扯太多邏輯處理業務。這些由Presenter負責的話狀況能夠改善不少。我建議將在頂級父類中將activity的生命週期在Presenter中實現一遍,而後生命週期有關的業務邏輯直接由Presenter來實現。網絡
Model不單單是javabean。Model是負責提供各種數據模型。在此基礎上我將Model拓展爲數據層提供數據交互。將javabean單獨爲數據層的一部分。
Model層的各個Model通常使用單例。這樣的好處在於這個惟一對象能夠管理一些數據供全部上層使用。
Model的單例對象架構
public class UserModel extends AbsModel{ public static UserModel getInstance() { return getInstance(UserModel.class); } @Override protected void onAppCreate(Context ctx) { super.onAppCreate(ctx); //初始化 } public void login(String number,String password,DataCallback<UserDetail> callback){ //進行登陸請求與回調,並保存返回帳號 } public void register(String tel,String password,String code,int gender,String nickname,StatusCallback callback){ //進行註冊請求與回調 } public void findPassword(String number,String code,String password,DataCallback<User> callback){ //進行找回密碼請求與回調 } public void certification(String number,String school,String realName,String stuCard,DataCallback<User> callback){ //進行認證請求與回調 } public void LoginOut(){ //登出操做 } }
既然Model層管理數據,而且是單例。他就有初始化的需求,好比在APP啓動時就請求數據,記錄信息,開始一個後臺線程與服務器同步信息等。這些操做與Presenter無關。是數據層自發的的功能。因此須要在Application啓動時進行Model的初始化。
但又要注意不能在Application的onCreate()進行過多操做,不然會啓動時間過長。因此可考慮在啓動時建立一個後臺線程,將即時性不強的初始化操做放到後臺線程。
對於Adapter是放在View好仍是Presenter好,這個問題確實難以解決。但在使用解耦的ViewHolder後這個問題便很明瞭。視圖的建立與改變全由ViewHolder管理。而後Adapter僅僅處理面向ViewHolder的邏輯。
而後ViewHolder屬於View,Adapter屬於Presenter。參考EasyRecyclerView
Adapter:
public class PersonAdapter extends RecyclerArrayAdapter<Person> { public PersonAdapter(Context context) { super(context); } @Override public BaseViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) { return new PersonViewHolder(parent); } }
ViewHolder: public class PersonViewHolder extends BaseViewHolder<Person> { private TextView mTv_name; private SimpleDraweeView mImg_face; private TextView mTv_sign; public PersonViewHolder(ViewGroup parent) { super(parent,R.layout.item_person); mTv_name = $(R.id.person_name); mTv_sign = $(R.id.person_sign); mImg_face = $(R.id.person_face); } @Override public void setData(final Person person){ mTv_name.setText(person.getName()); mTv_sign.setText(person.getSign()); mImg_face.setImageURI(Uri.parse(person.getFace())); } }
Rx訂閱發佈模式在MVP中做用很大。能夠極大簡化層間通信的處理。View向Presenter訂閱數據。Presenter能夠向Model層訂閱數據。造成一個數據鏈。數據能夠直接鏈式到達View層。優雅易拓展。
Presenter
public class QuestionShowPresenter extends BeamDataActivityPresenter<QuestionShowActivity,Question> { @Override protected void onCreate(QuestionShowActivity view, Bundle savedState) { super.onCreate(view, savedState); QuestionModel.getInstance().getQuestion(1).subscribe(this); } }
View
public class QuestionShowActivity extends BeamDataActivity<QuestionShowPresenter,Question> { @Override public void setData(Question data) { //顯示數據 } @Override public void setError(Throwable e) { //顯示錯誤 } }
Beam是我作的一套基於MVP模式的快速開發框架。參考了nucleus。上面的示例代碼都是使用了這個(爲方便複製的這個框架demo代碼.= =)。定義了一套開發規範。並提供了基於這套規範的Activity,Fragment,Presenter,Model等父類及控件和API等,完成APP開發過程當中大量繁瑣工做。並進行了一系列優化。詳情看這裏
示例