这篇文章的分享起因是因为上篇关于Properties的保存不了,调用SavePropertiesAsync()方法也不行,因此我但愿经过操做文件的方式保存个人须要的数据,而后我看了一下电子书中的第二十章和须要相关知识的第九章,这篇文章中的内容则是我学习这两章的一点记录和分享,仍是那样,有错请留言指正,谢谢!linux
不一样的平台存在着一些特定的API,经过在电子书中两章的学习,实践一下如何调用这些API和将这些API封装成公共的库,供之后的项目调用。以一个显示平台信息的小实例开始作一个简单的演示,其运行效果以下:app
C#代码以下(就是电子书中的实例,只不过只有IOS和Android的):异步
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App3.Views.DisplayModelAndVersion"> <StackLayout Padding="20"> <StackLayout VerticalOptions="CenterAndExpand"> <Label Text="Device Model:" /> <ContentView Padding="10, 0, 0, 0"> <Label x:Name="modelLabel" FontSize="Large" FontAttributes="Bold" /> </ContentView> </StackLayout> <StackLayout VerticalOptions="CenterAndExpand"> <Label Text="Operating System Version:" /> <ContentView Padding="10, 0, 0, 0"> <Label x:Name="versionLabel" FontSize="Large" FontAttributes="Bold" /> </ContentView> </StackLayout> </StackLayout> </ContentPage> #if __IOS__ using UIKit; #elif __ANDROID__ using Android.OS; #endif namespace App3.Views
{ public partial class DisplayModelAndVersion: ContentPage { public PlatInfoSap1Page () { InitializeComponent (); #if __IOS__ UIDevice device = new UIDevice(); modelLabel.Text = device.Model.ToString(); versionLabel.Text = String.Format("{0} {1}", device.SystemName, device.SystemVersion); #elif __ANDROID__ modelLabel.Text = String.Format("{0} {1}", Build.Manufacturer, Build.Model); versionLabel.Text = Build.VERSION.Release.ToString(); #endif } } }
记得在程序集中添加对Mono.Android和Xamarin.IOS的引用。学习
也许只有这一个,你看不出很麻烦,可是若是你要调用更多的特定的API,那么能够想见,你的代码中将会有许多的“#if __IOS__ xxxxx #elif __ANDROID__ xxxxxx #endif”这样的代码,那能不能把这些特定的API封装在其相应的平台,实现分平台的调用呢,固然是能够的。。。。。。我就不写其余的废话,就是经过DependencyService来实现的,直接上代码:ui
添加如上图所的接口和类(Sorry,下面那个箭头搞错了)阿里云
public interface IPlatformInfo { string GetModel(); string GetVersion(); } public class PlatformInfo { IPlatformInfo fileHelper = DependencyService.Get<IPlatformInfo>(); public string GetModel() { return fileHelper.GetModel(); } public string GetVersion() { return fileHelper.GetVersion(); } } [assembly: Dependency(typeof(App3.Droid.PlatformInfo))] namespace App3.Droid { class PlatformInfo : IPlatformInfo { public string GetModel() { return string.Format("{0} {1}", Build.Manufacturer, Build.Model); } public string GetVersion() { return Build.VERSION.Release; } } }
记住DependencyService和Dependency的命名空间是Xamarin.Froms,我开始没注意就被坑了。IOS的代码没有什么变化,就是命名空间变了,就不贴出来了,我也没写。。。spa
当你看到“assembly: Dependency”这个的时候,你也许就联想到了反射--是的,就是经过反射。建议你们在实现相关的功能是首先使用DependencyService,至于缘由我就不用我蹩脚的英语给你们翻译了,直接上原文:.net
DependencyService is not the only way to implement platform-specific calls in a PCL. Adventurous developers might want to use dependency-injection techniques to configure the PCL to make calls into the platform projects. But DependencyService is very easy to use, and it eliminates most reasons to use a Shared Asset Project in a Xamarin.Forms application.翻译
如今咱们继续说说如何把这些设置成公共的库,便于之后的项目调用,其实很简单,就像咱们新建一个Xamarin.Froms项目同样,新建一个Xamarin.Platfrom.Tools项目,而后把上面PlatformInfo相关的类和接口再写一遍,建议再添加一个Init的cs文件,代码中不用实现什么具体的东西,其功能就是确保dll正确的加载了。3d
对于文件的操做,电子书中有个小标题“Good news and bad news”,当中的主要内容就是告诉你们操做文件的是System.IO命名空间(该命名空间下还有个FileInfo类)下的File类在Android和IOS是能够共用的,可是在Windows的三个平台不行,最明显的一个区别就是Windows的三个平台的文件操做是异步的,作过WP开发的应该知道。鉴于目前的移动端的情形,和使用Xamarin开发的主要需求,那个”bad news“咱们基本能够忽略了(开发Windows的仍是用UWP吧)。
在移动端,基本上都包含一些基本的文件夹,好比Pictures、Music等这些都是公共的,而APP所访问的文件夹和文件还有一个限制,在WP开发中有个名词叫“隔离存储”或者“独立存储”,IOS和Android我并无太多的接触,但这方面应该都是大致相同的,因此每一个应用程序都除了能访问前面说的公共的文件夹和文件以外,都只能访问本身的程序“域”下面的文件夹和文件,作过移动开发或者了解移动开发的应该都知道。对于这些文件夹,Xamarin定义一个SpecialFolder的枚举,其中的MyDocuments就是咱们本身的APP才能访问的。经过下面的示例继续:
添加如上图所示的红色箭头的类和接口,代码以下(限于文章的篇幅,我就不贴整个代码,只上GetFiles的):
namespace App3.TestFile { public interface IFileHelper { IEnumerable<string> GetFiles();
} } namespace App3.TestFile { public class FileHelper { IFileHelper fileHelper = DependencyService.Get<IFileHelper>(); public IEnumerable<string> GetFiles() { return fileHelper.GetFiles(); }
} }
[assembly: Dependency(typeof(App3.Droid.FileHelper))]
namespace App3.Droid
{
class FileHelper : IFileHelper
{
public IEnumerable<string> GetFiles()
{
// Sort the filenames.
//string path = GetDocsFolder();
//IEnumerable<string> filenames =
// from filepath in new List<string> { path }
// select filepath;
IEnumerable<string> filenames =
from filepath in Directory.EnumerateFiles(GetDocsFolder())
select filepath;
return filenames;
}
string GetDocsFolder()
{
return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
}
}
}
至于XAML呢么就是一个简单的ListView,这个倒没什么说的。你们本身试一试吧。
这里的文件操做能知足咱们许多的需求了,可是有时候咱们在项目中添加一个图片、文件或者其余的,该怎么办呢。。。下次再说操做本地文件的事吧!
其实最开始的那版文字描述更通顺一些,结果出去吃了饭,回来发现没有自动保存,并且之前写的忘了,而后又从新写了,如今本身读了一次。。。
对了,.net core发布了,最近也在摸索,相比于Xamarin,分享和关注的人也更多,学习起来仍是很方便的,上周本身也买了一个最便宜的阿里云的在玩,无语啊,linux也成必学的了,伤心~共勉!