好几个月没写文章了,使用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是从经典的mvc模式演变而来的,但是mvc模式中的View是可以直接访问model的,两者的重大的区别在于:mvp中presenter隔断model与view的通信,view与model的交互通过presenter来实现。

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层的引用来操作。 
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/ 
效果图如下: 
 
项目的结构如下: 
 
新建peresenter文件夹,GongAnPresenter.cs 如下:

     public class GongAnPresenter
{
private IGongAnView view;
public GongAnPresenter(IGongAnView view)
{
this.view = view;
}
public async void showResult(string sitedomain)
{
var result = await SearchGongAn.getGonganDetail(sitedomain);
if (result != null && result.status == )
view.getServiceGongAnSuccess(result.data);
else if (result == null)
{
view.getServiceGonganFail("请求失败");
}
else
{
view.getServiceGonganFail("没有备案:status:"+result.status);
}
}
}
 

新建Views文件夹 ,IGongAnView.cs 接口 如下

    public interface IGongAnView
{
void getServiceGongAnSuccess(Data model);
void getServiceGonganFail(string error);
}

新建Model文件夹,SearchGongAn.cs如下:

     public class SearchGongAn
{
private static string url= "https://www.sojson.com/api/gongan/{0}";
public static async System.Threading.Tasks.Task<GongAnModel> getGonganDetail(string city)
{
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format(url, city));
request.Method = "get";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
string result = await streamReader.ReadToEndAsync();
GongAnModel model = JsonConvert.DeserializeObject<GongAnModel>(result);
streamReader.Close();
responseStream.Close();
return model;
}
catch (Exception ex)
{
Log.Info("ex",ex.ToString());
return null;
}
}
}
 

Mainactivity.cs

  [Activity(Label = "PeresenterForXamarinAndroid", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity,IGongAnView,View.IOnClickListener
{
TextView txt_result;
Button btn_search;
EditText btn_sitedomain;
GongAnPresenter presenter;
ProgressDialog progressDialog;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
txt_result = FindViewById<TextView>(Resource.Id.txt_result);
btn_search = FindViewById<Button>(Resource.Id.btn_search);
btn_sitedomain = FindViewById<EditText>(Resource.Id.btn_sitedomain);
presenter = new Peresenter.GongAnPresenter(this);
progressDialog = new ProgressDialog(this);
progressDialog.SetTitle("搜索公网备案");
progressDialog.SetMessage("正在搜索,请稍后.....");
btn_search.SetOnClickListener(this);
} public void OnClick(View v)
{
if (v.Id == Resource.Id.btn_search)
{
string sitedomain = btn_sitedomain.Text;
string pattern = @"^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$";
Regex reg = new Regex(pattern);
if (string.IsNullOrEmpty(sitedomain))
{
Toast.MakeText(this, "请输入域名", ToastLength.Short).Show();
}
else if (reg.IsMatch(sitedomain))
{
progressDialog.Show();
presenter.showResult(sitedomain);
}
else
{
Toast.MakeText(this, "域名错误,请重新输入", ToastLength.Short).Show();
}
}
}
public void getServiceGongAnSuccess(Data model)
{
progressDialog.Hide();
txt_result.Text = "工信部更新日期:" + model.cdate.ToShortDateString() + "\n公司地址:" + model.comaddress + "\n公司名称:" + model.comname + "\n网备案号:" + model.id + "\n域名" + model.sitedomain + "\n简称:" + model.sitename;
} public void getServiceGonganFail(string error)
{
progressDialog.Hide();
txt_result.Text = "查询失败";
Toast.MakeText(this,error,ToastLength.Short).Show();
}
}

总结

纸上得来终觉浅,绝知此事要躬行。只要不断实践,丰富项目经验,架构模式在初学者前期并不是那么重要。android开发无外乎就三种架构MVC、MVP、MVVM。MVP模式简单易用非常容易上手,Presenter隔断了View和Model的联系,作为两者沟通的桥梁,在Activityhe fragment中你的代码就不会变得臃肿,杂乱了。 
引用一句我非常喜欢的话:

架构只是一种思维模式,不管是MVC、MVP还是MVVM,都只是一种思考问题的思维,其目的还是要解决变成过程中高内聚、低耦合、可维护、易测试。

MVP架构在xamarin android中的简单使用的更多相关文章

  1. Xamarin.Android中使用android:onClick="xxx"属性

    原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...

  2. [置顶] Xamarin android中使用signalr实现即时通讯

    前面几天也写了一些signalr的例子,不过都是在Web端,今天我就来实践一下如何在xamarin android中使用signalr,刚好工作中也用到了这个,也算是总结一下学到的东西吧,希望能帮助你 ...

  3. Xamarin Android 中Acitvity如何传递数据

    在xamarin android的开发中,activity传递数据非常常见,下面我也来记一下在android中activity之间传递数据的几种方式, Xamarin Android中Activity ...

  4. 5、xamarin.android 中如何对AndroidManifest.xml 进行配置和调整

    降低学习成本是每个.NET传教士义务与责任. 建立生态,保护生态,见者有份. 我们在翻看一些java的源码经常会说我们要在AndroidManifest.xml 中添加一些东西.而我们使用xamari ...

  5. SignalR在Xamarin Android中的使用

    原文:SignalR在Xamarin Android中的使用 ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 ...

  6. Xamarin.Android中使用ResideMenu实现侧滑菜单

    上次使用Xamarin.Android实现了一个比较常用的功能PullToRefresh,详情见:Xamarin. Android实现下拉刷新功能 这次将实现另外一个手机App中比较常用的功能:侧滑菜 ...

  7. 基于Xamarin Android实现的简单的浏览器

    最近做了一个Android浏览器,当然功能比较简单,主要实现了自己想要的一些功能……现在有好多浏览器为什么还要自己写?当你使用的时候总有那么一些地方不如意,于是就想自己写一个. 开发环境:Xamari ...

  8. android中实现简单的聊天功能

    这个例子只是简单的实现了单机版的聊天功能,自己跟自己聊,啦啦~~ 主要还是展示RecyclerView控件的使用吧~ 参考我之前写的文章: android中RecyclerView控件的使用 andr ...

  9. Gradle在Android中的简单使用

    Gradle在Android中简单的使用 还望支持个人博客站:http://www.enjoytoday.cn Android Studio 使用gradle进行工程构建,为了更好的了解整个andro ...

随机推荐

  1. DBUtils源码分析

    其实,在这篇文章里,我只是分析了dbutis的query的运作流程. 至于类为什么要这样设计,蕴含的设计模式等等高级知识点咱们在下节再探讨. 先看看最简单的DBUtils是如何工作的. 数据库里有一张 ...

  2. 【面试笔试算法】Problem 1 : DP滑雪问题--网易互联网算法实习生2017笔试题

    Description Michael喜欢滑雪百这并不奇怪,因为滑雪的确很刺激.可是 为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  3. RHEL6 安装KVM

    RHEL6 安装KVM # egrep '^flags.*(vmx|svm)' /proc/cpuinfo 有显示说明CPU支持VT功能 2.在主板BIOS中开启CPU的Virtual Technol ...

  4. Demonstration of DB Query Analyzer 6.03 Installation and Running on Microsoft Windows 8

    Demonstration of DB Query Analyzer 6.03 Installation and Running on Microsoft Windows 8 Ma Genfeng ( ...

  5. 在 Linux 下用 mkdir 命令来创建目录和子目录

    mkdir 是什么呢 Mkdir 是一个用来在 Linux 系统下创建目录的命令.此命令属于内建命令. 运行 mkdir 命令 你可以在你的控制台直接键入 mkdir 来使用它. $ mkdir 默认 ...

  6. Linux - test测试标志的意思总结

    测试的标志 代表意义 1. 关於某个档名的『文件类型』判断,如 test -e filename 表示存在否 -e 该『档名』是否存在?(常用) -f 该『档名』是否存在且为文件(file)?(常用) ...

  7. iOS中判断照片和相机权限

    1.照片权限判断 在iOS6之后,app中使用照片(即自带相册)需要用户权限验证,所以我们可以做一个权限判断给出友好的提示或者界面效果. 相册判断需要导入 <AssetsLibrary/Asse ...

  8. linu下C语言之BMP图片操作编程(上)

    BMP文件格式,也被称为位图图像文件或与设备无关的位图文件格式(DIB)或者只是一个位图,是 一个光栅图形 图像文件格式使用 来存储位图,数字,图片,独立的显示设备. 微软已经定义了一个特定的表示颜色 ...

  9. MIDle生命周期详解,以及工作原理

    当MIDlet被应用程序管理器成功地初始化之后,就开始展开了它的生命周期.MIDlet的生命周期完全由应用程序管理器控制,也就是说,当MIDlet要从一个状态变成另外一个状态时,应用程序管理器会调用对 ...

  10. 数据结构---栈C语言实现

    #include <stdio.h> #include <stdlib.h> #define uchar unsigned char #define uint unsigned ...