MVP架构在xamarin android中的简单使用

小编 2026-07-03 阅读:1240 评论:0
好几个月没写文章了,使用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(数据存取); 
MVP架构在xamarin android中的简单使用 
Model:负责数据的处理、请求网络数据、读取本地数据、检验等 
View:UI操作,控件的实际处理,更新Model层的数据,负责用户请求通知Controller 
Controller:Activity和Fragment,初始化各种控件,加载数据、逻辑的处理,职责比较多。

什么是MVP

mvp是从经典的mvc模式演变而来的,但是mvc模式中的View是可以直接访问model的,两者的重大的区别在于:mvp中presenter隔断model与view的通信,view与model的交互通过presenter来实现。

mvp将controller改成了peresenter提出者,也改变了通信的方向,是一个MVC的改良版,MVP的结构如下: 
MVP架构在xamarin android中的简单使用
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层的引用来操作。 
2.便于测试,维护性提高,代码结构更加清晰,可以明显看到Activity和 
3.View与Model分离使工程的整体架构和代码结构非常清晰(不再是所有的业务和逻辑都糅合在Activity、Fragment里了),易于理解和上手。 
mvp的缺点是: 
代码更加复杂,代码量增加。 在使用中我也发现了很多弊端,每个Activity、Fragment都需要划分一套MVP,这无形之中增加很多类和接口,每次通信都需要繁琐的接口传递信息,这些确定也演化了许多版本的MVP,更多详细可以参考:传统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/ 
效果图如下: 
MVP架构在xamarin android中的简单使用 
项目的结构如下: 
MVP架构在xamarin android中的简单使用 
新建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             else18             {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                 else40                 {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() + "
公司地址:" + model.comaddress + "
公司名称:" + model.comname + "
网备案号:" + model.id + "
域名" + model.sitedomain + "
简称:" + 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,都只是一种思考问题的思维,其目的还是要解决变成过程中高内聚、低耦合、可维护、易测试。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表