編輯:關於Android編程
隨著MVP概念的興起和發展,MVP使用越來越廣泛,當然MVP的優勢也越來越被認同,在合作開發功能模塊細分中MVP有著得天獨厚的優勢。本篇文章就來簡單的說說如何使用MVP。
MVP是MVC的變種,其實是一種升級。要說MVP就要說說MVC,在MVC中Activity其實是View層級,但是通常在使用中Activity即使View也是Controller,並沒有將View層和Controller層進行分離,
耦合度大大提高,非常不利於項目的管理。這時候MVP就應運而生了。
Model View Presenter
MVP把Activity中的UI邏輯抽象成View接口,把業務邏輯抽象成Presenter接口,Model類還是原來的Model。
在MVP模式中Activity的功能就是響應生命周期和顯示界面,具體其他的工作都丟到了Presenter層中進行完成,Presenter其實是Model層和View層的橋梁。
具體的MVP的好處還有很多,就不詳細介紹了,下面看看如何使用MVP。
vc+x8MWko6y2+MfSxNHS1LzH16Gho8bkyrXSu7+qyrzP68yrtuDSssO709DKssO0wtHTw6Os1rvSqtTavt/M5c/uxL/W0Lbg0LS8uLTOo6w8YnIgLz4NCr7NxNzK7M+kTVZQxKPKvbXE0LS3qKOswO294tLizbyjrNLUvLDP7crcxuS0+MC0tcS6w7SmoaM8L3A+DQo8aDIgaWQ9"mvp的使用">MVP的使用
理論說了這麼多其實沒有什麼卵用,下面就來在代碼中看看如何使用吧。
先來看看項目中代碼結構,結構圖如下
通過代碼結構圖可以看到看出MVP結構層級分明(在項目中使用MVP最好通過模塊進行分層這樣便於管理且結構清晰),
先來看看View層代碼
ILoginView接口代碼如下
public interface ILoginView { public void onClearText(); public void onLoginResult(Boolean result, int code); }
可以看出ILoginView只是一個接口,簡單的定義了兩個方法。
看看ILoginView的實現類也就是我們的LoginActivity
LoginActivity代碼如下
public class LoginActivity extends AppCompatActivity implements ILoginView,View.OnClickListener{ private Button mLogin ; private Button mClear ; private EditText mName ; private EditText mPassWord ; ILoginPresenter loginPresenter ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLogin = (Button) findViewById(R.id.btn_login); mClear = (Button) findViewById(R.id.btn_clear); mName = (EditText) findViewById(R.id.et_name); mPassWord = (EditText) findViewById(R.id.et_password); mLogin.setOnClickListener(this); mClear.setOnClickListener(this); loginPresenter = new LoginPresenterCompl(this) ; } @Override public void onClearText() { mName.setText(""); mPassWord.setText(""); Toast.makeText(this,"clear",Toast.LENGTH_SHORT).show(); } @Override public void onLoginResult(Boolean result, int code) { mLogin.setEnabled(true); mClear.setEnabled(true); if(result){ Toast.makeText(this,"登陸成功: "+code,Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this,"登陸失敗:"+code,Toast.LENGTH_SHORT).show(); } } @Override public void onClick(View v) { int id = v.getId() ; String name = mName.getText().toString() ; String password = mPassWord.getText().toString() ; switch (id){ case R.id.btn_login : loginPresenter.doLogin(name,password); break ; case R.id.btn_clear : loginPresenter.clear(); break; } } }
布局文件如下
在LoginActivity中我們可以看到,LoginActivity實現了ILoginView接口,實現了未實現的方法,在代碼中可以看出LoginActivity並沒有做一些邏輯處理工作,數據處理的工作都是調用ILoginPresenter
完成的。下面就來看看ILoginPresenter
public interface ILoginPresenter { public void clear() ; public void doLogin(String name, String password) ; }
也是簡單的接口定義兩個未實現的方法。
看看其實現類LoginPresenterCompl
public class LoginPresenterCompl implements ILoginPresenter { private ILoginView loginView ; private User user ; @Inject public LoginPresenterCompl(ILoginView view){ loginView = view ; user = new User("張三","123456") ; } @Override public void clear() { loginView.onClearText(); } @Override public void doLogin(String name, String password) { boolean result = false ; int code = 0 ; if(name.equals(user.getName()) && password.equals(user.getPassword())){ result = true ; code = 1 ; }else{ result = false ; code = 0 ; } loginView.onLoginResult(result,code); } }
該實現類也比較簡單,定義了用戶名是張三,密碼是123456的一個登陸用戶,然後進行登陸和清除的操作。
OK這就完成了最簡單的MVP模式了。
看看model層的代碼
User的代碼如下
public class User { private String name ; private String password ; public User(String name,String password){ this.name = name ; this.password = password ; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
看完上述MVP的代碼後可能有的同學會說一個簡單的登陸就是簡單的驗證用戶名和密碼為什麼要設計的這麼復雜,可能有人會覺得還沒有以前的寫法簡單呢。但是這只是一個簡單的實現MVP的例子。
當項目越來越大,代碼越來越多的時候就能夠真正的體現出MVP模式的優勢了。
知道了什麼是MVP也知道了如何在項目中使用MVP,那MVP的優勢到底有哪些呢?
1、使Activity中的代碼更加簡潔
在傳統的項目中Activity兼顧著Controller和View,這使得其代碼分分鐘上千行(本人深受其害),這使得代碼難以理解難以維護,看到這樣的Activity就想吐。
使用MVP之後,Activity就能瘦身許多了,基本上只有FindView、SetListener以及Init的代碼。其他的就是對Presenter的調用,還有對View接口的實現。這種情形下閱讀代碼就容易多了,
而且你只要看Presenter的接口,就能明白這個模塊都有哪些業務,很快就能定位到具體代碼。Activity變得容易看懂,容易維護,以後要調整業務、刪減功能也就變得簡單許多。
2、方便進行單元測試
一般單元測試都是用來測試某些新加的業務邏輯有沒有問題,如果采用傳統的代碼風格,我們可能要先在Activity裡寫一段測試代碼,測試完了再把測試代碼刪掉換成正式代碼,
這時如果發現業務有問題又得換回測試代碼,咦,測試代碼已經刪掉了!好吧重新寫吧……
MVP中,由於業務邏輯都在Presenter裡,我們完全可以寫一個PresenterTest的實現類繼承Presenter的接口,現在只要在Activity裡把 Presenter的創建換成PresenterTest,
就能進行單元測試了,測試完再換回來即可。萬一發現還得進行測試,那就再換成PresenterTest吧。
3、避免Activity的內存洩露
APP發生OOM的最大原因就是出現內存洩露造成APP的內存不夠用,而造成內存洩露的兩大原因之一就是Activity洩露(Activity Leak)(另一個原因是Bitmap洩露(Bitmap Leak))。
Java一個強大的功能就是其虛擬機的內存回收機制,這個功能使得Java用戶在設計代碼的時候,不用像 C++ 用戶那樣考慮對象的回收問題。然而,Java用戶總是喜歡隨便寫一大堆對象,
然後幻想著虛擬機能幫他們處理好內存的回收工作。可是虛擬機在回收內存的時候,只會回收那些沒有被引用的對象,被引用著的對象因為還可能會被調用,所以不能回收。
Activity 是有生命周期的,用戶隨時可能切換Activity,當APP的內存不夠用的時候,系統會回收處於後台的Activity的資源以避免OOM。
采用傳統的模式,一大堆異步任務和對UI的操作都放在Activity裡面,比如你可能從網絡下載一張圖片,在下載成功的回調裡把圖片加載到Activity的ImageView裡面,
所以異步任務保留著對Activity的引用。這樣一來,即使Activity已經被切換到後台(onDestroy 已經執行),這些異步任務仍然保留著對Activity實例的引用,
所以系統就無法回收這個Activity實例了,結果就是Activity Leak。Android 的組件中,Activity 對象往往是在堆(Java Heap)裡占最多內存的,所以系統會優先回收Activity對象,
如果有Activity Leak,APP很容易因為內存不夠而 OOM。
采用MVP模式,只要在當前的Activity的onDestroy裡,分離異步任務對Activity的引用,就能避免Activity Leak。
以上就是MVP的簡單實現,可能示例代碼太簡單無法體現MVP的優勢,但是理解了MVP的思路在項目中使用MVP就才能夠真正體驗到MVP帶來的好處優勢。
簡述:相信很多學安卓的都是從java入門之後開始進行安卓的學習,而當我們面臨安卓線程的書寫的時候,發現安卓線程並不是我們想象中使用java的線程寫法就可以。java線程的
一、前言現在主流的加固平台有:梆梆加固,愛加密,360加固,騰訊加固,在之前的一篇文章中介紹了:如何脫掉“愛加密”的殼,現在這裡要脫掉另外一個平台
1、startService 在Android系統匿名共享內存(Anonymous Shared Memory)Java調用接口分析,http://blog
Socket簡介在說Socket之前,我們有必要先來簡單介紹一下TCP/IP協議族,TCP/IP(Transmission Control Protocol/Intern