閒來無事在家偶然翻到了以前整理的文檔和麪試要作到準備路線,雖然內容有點多,可是技多不壓身,多多益善git
本部份內容是關於Android進階的一些知識總結,涉及到的知識點比較雜,不過都 是面試中幾乎常問的知識點,也是加分的點。 關於這部份內容,可能須要有一些具體的項目實踐。在面試的過程當中,結合具體自 身實踐經歷,才能更加深刻透徹的描繪出來github
相關內容後續GitHub更新,想衝擊金三銀四的小夥伴能夠找找看看,歡迎star
( 順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)
MVP,MVC,MVVM
此處延伸:手寫 mvp 例子,與 mvc 之間的區別,mvp 的優點面試
MVP 模式,對應着 Model--業務邏輯和實體模型,view--對應着 activity,負責 View 的繪製以 及與用戶交互,Presenter--負責 View 和 Model 之間的交互,MVP 模式是在 MVC
模式的基礎上, 將 Model 與 View 完全分離使得項目的耦合性更低,在 Mvc
中項目中的 activity 對應着 mvc
中的 C--Controllor
,而項目中的邏輯處理都是在這個 C 中處理,同時 View 與 Model 之間的交 互,也是也就是說,mvc
中全部的邏輯交互和用戶交互,都是放在 Controllor
中,也就是 activity 中。View 和 model 是能夠直接通訊的。而 MVP 模式則是分離的更加完全,分工更加明確 Model--業務邏輯和實體模型,view--負責與用戶交互,Presenter 負責完成 View 於 Model 間的交互,MVP 和 MVC
最大的區別是 MVC
中是容許 Model 和 View 進行交互的,而 MVP 中很明顯,Model 與 View 之間的交互由 Presenter 完成。還有一點就是 Presenter
與 View 之 間的交互是經過接口的架構
MVP
,全稱 Model-View-Presenter 即模型-視圖-層現器。
提到MVP,就必需要先介紹一下它的前輩MVC,由於MVP正是基於MVC的基礎發 展而來的。兩個之間的關係也是源遠流長。MVC
,全稱Model-View-Controller,即模型-視圖-控制器。 具體以下:View
: 對應於佈局文件 Model
: 業務邏輯和實體模型 Controllor
: 對應於Activity
mvc
可是View
對應於佈局文件,其實能作的事情特別少,實際上關於該佈局文件中的數 據綁定的操做,事件處理的代碼都在Activity
中,形成了Activity
既像View
又像 Controller
,使得Activity
變得臃腫。 ide
而當將架構改成MVP之後,Presenter
的出現,將Actvity
視爲View層,Presenter
負 責完成View層與Model層的交互。佈局
如今是這樣的: View
對應於Activity
,負責View
的繪製以及與用戶交互 Model
依然是業務邏輯和實體模型 Presenter
負責完成View
於Model
間的交互 下面兩幅圖經過數據與視圖之間的交互清楚地展現了這種變化:MVC
模式下實際上就是Activty
與Model之間交互,View徹底獨立出來了。MVP
模式經過Presenter
實現數據和視圖之間的交互,簡化了Activity
的職責。同時 即避免了View
和Mode
l的直接聯繫,又經過Presenter
實現二者之間的溝通。 post
總結: MVP
模式減小了Activity
的職責,簡化了Activity
中的代碼,將複雜的邏輯代 碼提取到了Presenter
中進行處理,模塊職責劃分明顯,層次清晰。與之對應的好 處就是,耦合度更低,更方便的進行測試。學習
MVC
和MVP
的區別MVC
中是容許Model
和View
進行交互的,而MVP
中很明顯,Model
與View
之間的 交互由Presenter
完成。還有一點就是Presenter
與View
之間的交互是經過接口 的。測試
還有一點注意: MVC
中V對應的是佈局文件,MVP
中V對應的是Activity
。
大多數MVP
模式的示例都使用登陸案例進行介紹。由於簡單方便,同時能提現出 MVP
的特色。今天咱們也以此例進行學習。 使用MVP
的好處之一就是模塊職責劃 分明顯,層次清晰。 該例的結構圖便可展示此優勢。
在本例中,M0del
層負責對從登陸頁面獲取地賬號密碼進行驗證(通常須要請求服 務器進行驗證,本例直接模擬這一過程)。 從上圖的包結構圖中能夠看出,Model 層包含內容:
①實體類bean
②接口,表示Model層所要執行的業務邏輯
③接口實現類,具體實現業務邏輯,包含的一些主要方法
下面以代碼的形式一一展開。
①實體類bean
public class User { private String password; private String username; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public String toString() { return "User{" + "password='" + password + '\'' + ", username='" + username + '\'' + '}'; } }
封裝了用戶名、密碼,方便數據傳遞。
②接口
public interface LoginModel { void login(User user, OnLoginFinishedListener listener); }
其中OnLoginFinishedListener
是presenter
層的接口,方便實現回調presenter
,通知presenter
業務邏輯的返回結果,具體在presenter
層介紹。
③接口實現類
public class LoginModelImpl implements LoginModel { @Override public void login(User user, final OnLoginFinishedListener l istener) { final String username = user.getUsername(); final String password = user.getPassword(); new Handler().postDelayed(new Runnable() { @Override public void run() { boolean error = false; if (TextUtils.isEmpty(username)){ listener.onUsernameError();//model層裏面回調li stener error = true; } if (TextUtils.isEmpty(password)){ listener.onPasswordError(); error = true; } if (!error){ listener.onSuccess(); } } }, 2000); } }
實現Model層邏輯:延時模擬登錄(2s),若是用戶名或者密碼爲空則登錄失敗, 不然登錄成功。
視圖: 將Modle
層請求的數據呈現給用戶。通常的視圖都只是包含用戶界面(UI),而 不包含界面邏輯,界面邏輯由Presenter
來實現。
從上圖的包結構圖中能夠看出,View包含內容:
①接口,上面咱們說過Presenter與View交互是經過接口。其中接口中方法的定義是 根據Activity用戶交互須要展現的控件肯定的。
②接口實現類,將上述定義的接口中的方法在Activity中對應實現具體操做。
下面以代碼的形式一一展開。
①接口
public interface LoginView { //login是個耗時操做,咱們須要給用戶一個友好的提示,通常就是操做Progre ssBarvoid showProgress(); void hideProgress(); //login固然存在登陸成功與失敗的處理,失敗給出提示 void setUsernameError(); void setPasswordError(); //login成功,也給個提示 void showSuccess(); }
上述5個方法都是presenter
根據model
層返回結果須要view執行的對應的操做。
②接口實現類
即對應的登陸的Activity,須要實現LoginView
接口。
public class LoginActivity extends AppCompatActivity implements LoginView, View.OnClickListener { private ProgressBar progressBar; private EditText username; private EditText password; private LoginPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); progressBar = (ProgressBar) findViewById(R.id.progress); username = (EditText) findViewById(R.id.username); password = (EditText) findViewById(R.id.password); findViewById(R.id.button).setOnClickListener(this); //建立一個presenter對象,當點擊登陸按鈕時,讓presenter去調用mode l層的login()方法,驗證賬號密碼 presenter = new LoginPresenterImpl(this); } @Override protected void onDestroy() { presenter.onDestroy(); super.onDestroy(); } @Override public void showProgress() { progressBar.setVisibility(View.VISIBLE); } ..... }
View
層實現Presenter
層須要調用的控件操做,方便Presenter
層根據Model
層返回 的結果進行操做View層進行對應的顯示。
Presenter
是用做Model
和View
之間交互的橋樑。 從上圖的包結構圖中能夠看出, Presenter
包含內容:
①接口,包含Presenter須要進行Model和View之間交互邏輯的接口,以及上面提到 的Model層數據請求完成後回調的接口。
②接口實現類,即實現具體的Presenter類邏輯。
下面以代碼的形式一一展開。
①接口
public interface OnLoginFinishedListener { void onUsernameError(); void onPasswordError(); void onSuccess(); }
當Model
層獲得請求的結果,須要回調Presenter
層,讓Presenter
層調用View
層的 接口方法。
public interface LoginPresenter { void validateCredentials(User user); void onDestroy(); }
登錄的Presenter
的接口,實現類爲LoginPresenterImpl
,完成登錄的驗證,以及銷 毀當前view
。
②接口實現類
public class LoginPresenterImpl implements LoginPresenter, OnLog inFinishedListener { private LoginView loginView; private LoginModel loginModel; public LoginPresenterImpl(LoginView loginView) { this.loginView = loginView; this.loginModel = new LoginModelImpl(); } @Override public void validateCredentials(User user) { if (loginView != null) { loginView.showProgress(); } loginModel.login(user, this); } @Override public void onDestroy() { loginView = null; } @Override public void onUsernameError() { if (loginView != null) { loginView.setUsernameError(); .... }
因爲presenter
完成兩者的交互,那麼確定須要兩者的實現類(經過傳入參數,或者 new)。 presenter
裏面有個OnLoginFinishedListener
, 其在Presenter
層實現,給Model
層 回調,更改View
層的狀態, 確保 Model
層不直接操做View
層。
示例展現:
View
與Model
並不直接交互,而是使用Presenter
做爲View
與Model
之間的橋樑。其中Presenter
中同時持有View
層的Interface
的引用以及Model
層的引用,而View
層持有Presenter
層引用。當View層某個界面須要展現某些數據的時候,首先會調用 Presenter
層的引用,而後Presenter
層會調用Model
層請求數據,當Model
層數據加 載成功以後會調用Presenter
層的回調方法通知Presenter
層數據加載狀況,最後 Presenter
層再調用View
層的接口將加載後的數據展現給用戶。
相關內容後續GitHub更新,想衝擊金三銀四的小夥伴能夠找找看看,歡迎star
( 順手留下GitHub連接,須要獲取相關面試等內容的能夠本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)