這篇文章的分享起因是因爲上篇關於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也成必學的了,傷心~共勉!