MVP架構在xamarin android中的簡單使用
好幾個月沒寫文章了,使用xamarin android也快接近兩年,還有一個月職業生涯就到兩個年了,從剛出來啥也不會了,到現在回頭看這個項目,真jb操蛋(真辛苦了實施的人了,無數次吐槽怎麽這麽醜),怪自己太年輕了,還好是給指定行業的人使用。 重新學習思考之後,再看自己在項目中的某些實現的代碼,的確不盡人意,甚至想罵自己。
項目經常改,改來該去,代碼一直增加,一個fragment也沒什麽功能,接近1000行的代碼,用region括起來,開看起來還挺整齊的,找的時候就涼了。究其原因,沒有一種模式,所有的邏輯全寫在controller(fragment和activity裏面),當然不管了解不了解什麽框架模式、設計模式。最主要、最基本的還是實現功能和良好的用戶體驗,一些小的項目,不需要頻繁修改需求甚至不需要MVP、MVC等模式來設計,那樣反而有點刻意設計,代碼復雜臃腫。關於android中mvp架構的介紹文章非常豐富,這裏我只是做一個學習的記錄,溫故而知新。
程序的思想都是通用的,搞.net對於mvc框架應該是非常熟悉,webform用的目前應該不是很多。先說說android中 MVC,mvc分為三部分 :視圖(View用戶界面)、Controller(fragmnet、activity控制器業務邏輯)、Model(數據存取);
Model:負責數據的處理、請求網絡數據、讀取本地數據、檢驗等
View:UI操作,控件的實際處理,更新Model層的數據,負責用戶請求通知Controller
Controller:Activity和Fragment,初始化各種控件,加載數據、邏輯的處理,職責比較多。
什麽是MVP
mvp將controller改成了peresenter提出者,也改變了通信的方向,是一個MVC的改良版,MVP的結構如下:
Model:存取數據,網絡數據、SharedPreferences、sqlite等數據的存取
Presenter:訂閱,負責View和Model的交互,隔斷View層和Model層的交互。調用View中的相應方法展示數據
View:Fragment、Activity、ViewGroup 這一層,處理用戶的交互和事件,並觸發Presenter中的相應操作
mvp的優點是:
1.view與model不發生任何交互,view層不能持有Model層的引用,不能直接去更新Model層,必須通過Presenter層,Presenter層中也不能直接操作View及相關的UI控件,必須通過View層的引用來操作。
3.View與Model分離使工程的整體架構和代碼結構非常清晰(不再是所有的業務和邏輯都糅合在Activity、Fragment裏了),易於理解和上手。
mvp的缺點是:
代碼更加復雜,代碼量增加。
實踐是檢驗真理的唯一標準,下面通過一個簡單的例子獲取天氣預報信息看看,如何在xamarin android項目如何使用MVP架構吧
使用mvp架構實現查詢公網備案的例子
天氣預報的接口:https://www.sojson.com/api/gongan/域名,根據域名查詢備案信息
返回的格式是json.
如果你想更深入地了解mvp架構,可以參看一下google官方MVP框架源碼解析之TODO-MVP
https://github.com/googlesamples/android-architecture/tree/todo-mvp/
效果圖如下:
項目的結構如下:
新建peresenter文件夾,GongAnPresenter.cs 如下:
1 public class GongAnPresenter 2 { 3 private IGongAnView view; 4 public GongAnPresenter(IGongAnView view) 5 { 6 this.view = view; 7 } 8 public async void showResult(string sitedomain) 9 { 10 var result = await SearchGongAn.getGonganDetail(sitedomain); 11 if (result != null && result.status == 200) 12 view.getServiceGongAnSuccess(result.data); 13 else if (result == null) 14 { 15 view.getServiceGonganFail("請求失敗"); 16 } 17 else 18 { 19 view.getServiceGonganFail("沒有備案:status:"+result.status); 20 } 21 } 22 }
新建Views文件夾 ,IGongAnView.cs 接口 如下
public interface IGongAnView { void getServiceGongAnSuccess(Data model); void getServiceGonganFail(string error); }
新建Model文件夾,SearchGongAn.cs如下:
1 public class SearchGongAn 2 { 3 private static string url= "https://www.sojson.com/api/gongan/{0}"; 4 public static async System.Threading.Tasks.Task<GongAnModel> getGonganDetail(string city) 5 { 6 try 7 { 8 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format(url, city)); 9 request.Method = "get"; 10 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 11 Stream responseStream = response.GetResponseStream(); 12 StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); 13 string result = await streamReader.ReadToEndAsync(); 14 GongAnModel model = JsonConvert.DeserializeObject<GongAnModel>(result); 15 streamReader.Close(); 16 responseStream.Close(); 17 return model; 18 } 19 catch (Exception ex) 20 { 21 Log.Info("ex",ex.ToString()); 22 return null; 23 } 24 } 25 }
Mainactivity.cs
1 [Activity(Label = "PeresenterForXamarinAndroid", MainLauncher = true, Icon = "@drawable/icon")] 2 public class MainActivity : Activity,IGongAnView,View.IOnClickListener 3 { 4 TextView txt_result; 5 Button btn_search; 6 EditText btn_sitedomain; 7 GongAnPresenter presenter; 8 ProgressDialog progressDialog; 9 protected override void OnCreate(Bundle bundle) 10 { 11 base.OnCreate(bundle); 12 SetContentView(Resource.Layout.Main); 13 txt_result = FindViewById<TextView>(Resource.Id.txt_result); 14 btn_search = FindViewById<Button>(Resource.Id.btn_search); 15 btn_sitedomain = FindViewById<EditText>(Resource.Id.btn_sitedomain); 16 presenter = new Peresenter.GongAnPresenter(this); 17 progressDialog = new ProgressDialog(this); 18 progressDialog.SetTitle("搜索公網備案"); 19 progressDialog.SetMessage("正在搜索,請稍後....."); 20 btn_search.SetOnClickListener(this); 21 } 22 23 public void OnClick(View v) 24 { 25 if (v.Id == Resource.Id.btn_search) 26 { 27 string sitedomain = btn_sitedomain.Text; 28 string pattern = @"^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$"; 29 Regex reg = new Regex(pattern); 30 if (string.IsNullOrEmpty(sitedomain)) 31 { 32 Toast.MakeText(this, "請輸入域名", ToastLength.Short).Show(); 33 } 34 else if (reg.IsMatch(sitedomain)) 35 { 36 progressDialog.Show(); 37 presenter.showResult(sitedomain); 38 } 39 else 40 { 41 Toast.MakeText(this, "域名錯誤,請重新輸入", ToastLength.Short).Show(); 42 } 43 } 44 } 45 public void getServiceGongAnSuccess(Data model) 46 { 47 progressDialog.Hide(); 48 txt_result.Text = "工信部更新日期:" + model.cdate.ToShortDateString() + "\n公司地址:" + model.comaddress + "\n公司名稱:" + model.comname + "\n網備案號:" + model.id + "\n域名" + model.sitedomain + "\n簡稱:" + model.sitename; 49 } 50 51 public void getServiceGonganFail(string error) 52 { 53 progressDialog.Hide(); 54 txt_result.Text = "查詢失敗"; 55 Toast.MakeText(this,error,ToastLength.Short).Show(); 56 } 57 }
總結
紙上得來終覺淺,絕知此事要躬行。只要不斷實踐,豐富項目經驗,架構模式在初學者前期並不是那麽重要。android開發無外乎就三種架構MVC、MVP、MVVM。MVP模式簡單易用非常容易上手,Presenter隔斷了View和Model的聯系,作為兩者溝通的橋梁,在Activityhe fragment中你的代碼就不會變得臃腫,雜亂了。
引用一句我非常喜歡的話:
架構只是一種思維模式,不管是MVC、MVP還是MVVM,都只是一種思考問題的思維,其目的還是要解決變成過程中高內聚、低耦合、可維護、易測試。
MVP架構在xamarin android中的簡單使用