編輯:Android資訊
所謂MVP(Model-View-Presenter)模式。是將APP的結構分為三層:
view 層主要負責:
presenter 層主要負責:
model層主要負責:
如圖示,裡面的activity,presenter,model均為例子:
將復雜的功能分割為各層內的小問題。各層內功能單一。這樣易於功能修改拓展與Debug。
解耦的設計,獨立的模塊,更有利於分工開發與測試。
Activity會在很多情況下被系統重啟:
當用戶旋轉屏幕
在後台時內存不足
改變語言設置
attache 一個外部顯示器等。
正確的方式應該是:
Presenter與Activity的綁定關系應由靜態類管理。而不是由Activity管理。當Activity意外重啟時Presenter不應重啟。Activity重啟時,Presenter與Activity重新綁定,根據數據恢復Activity狀態。
而當Activity真正銷毀時。對應Presenter才應該跟隨銷毀。
這樣處理可以解決以下2個很實際的問題:
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開發過程中大量繁瑣工作。並進行了一系列優化。詳情看這裡
示例:https://github.com/Jude95/Joy
桌面應用程序與浏覽器端的自動化測試都已經歷了十年的發展,無論是從工具上還是項目管理方 法論上都已經趨於成熟。而移動設備端應用程序的自動化測試近兩年才剛起步,似乎一
Android安全加密專題文章索引 Android安全加密:對稱加密 Android安全加密:非對稱加密 Android安全加密:消息摘要Message Dig
Android安全加密專題文章索引 Android安全加密:對稱加密 Android安全加密:非對稱加密 Android安全加密:消息摘要Message Dig
正如大家所見,這是本英文書,而由於國內的gradle翻譯資料不全,所以特次開辟專欄,翻譯gradle for android這本書,同時添加自己的心得體會以及在實