从Xamarin.Essentials谈Xamarin库的封装
編者語:Xamarin在國內的推廣還需要努力,其實這真的是移動端開發的一大福音,畢竟用一份代碼的時間可以生成iOS/Android/Windows/Linux/macOS/Tizen多個平臺,而且是原生的性能。Xamarin在Build 2018發布的新功能有Xamarin.Essentials(點擊查看) , Hyper-V for Xamarin Android Emulator ,還有Xamarin.Forms 3.0。Xamarin.Forms 3.0 和 Xamarin.Essentials 都會是一個質的飛躍。Xamarin.Forms 有全新的布局FlexLayout ,更好地和原生控件對接,還新增支持GTK+/Tizen。而Xamarin.Essentials的發布則大大提升開發的效率,把因為平臺差異造成的代碼不一致的底層接口重新做了歸一,這樣做提升了編碼效率。
? ? 在Build2018前的兩周左右,我拿到了Xamarin.Essentials的測試版本(基于nda我只能等到現在才能發布),這是一個為訪問一些設備硬件和底層給iOS/Android/UWP三個平臺做的統一接口,適配了.NET Standard 2.0(當然也包含.NET Standard 1.0 / iOS / Android)。通過Xamarin.Essentails你可以非常快捷地訪問不同平臺的攝像頭,地理位置,網絡檢測,更能調用如打電話,相冊,通訊錄等相當方便實用。如我需要了解設備信息的時候,通過Xamarin.Essentails就是一句非常簡單的話就可以完成了
?
?
? ? ? 運行生成效果
? ? ??
? ? ?話說回來,在Xamarin.Essential之前,其實Xamarin也推出了Xamarin.Mobile(點擊查看)和Plugin(點擊查看) 。我們先來看看這兩位舊人所做的事,如果對比代碼其實也差不多,通過PCL的方式對設備底層API進行訪問。(ps : 圖一是Xamarin.Mobile , 圖二Xamarin.Plugins)
? ? ??? ?
? ? ? 看看上面的代碼是比較有趣,可以預想到用原生方法寫一個攝像頭調用你可能需要更多的工作,而且這更接近.NET程序員的使用習慣。假若你希望為Xamarin打造一個跨平臺的,也能針對不同平臺底層操作,又有一個通用接口的庫,這三個通用組件的源碼就是很好的教程。
? ? ? 在Xamarin中實現跨平臺訪問,方法有幾種:
? ? ? 1. 通過檢測平臺的方式,最常用的是宏定義? ? ? ??
<span style="font-size:12px;">
#if __IOS__
// iOS-specific code
#endif
#if __TVOS__
// tv-specific stuff
#endif
#if __WATCHOS__
// watch-specific stuff
#endif
#if __ANDROID__
// Android-specific code
#endif
</span>
? 2. 或者通過代碼的方式, Xamarin.Forms.Device.Idiom去完成
<span style="font-size:12px;">? ? ? ? ??
? ? ? ? ??if (Xamarin.Forms.Device.Idiom == TargetIdiom.Phone)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? MainPage = new NavigationPage(new MyPage());
? ? ? ? ? ? }
? ? ? ? ? ? else if(Xamarin.Forms.Device.Idiom == TargetIdiom.Tablet)
? ? ? ? ? ? {
? ? ? ? // etc
? ? ? ? ? ? }
? ? ? ? ? ? else if(Xamarin.Forms.Device.Idiom == TargetIdiom.Desktop)
? ? ? ? ? ? {
? ? ? ? // etc
? ? ? ? ? ? }
? ? ? ? ? ? else if (Xamarin.Forms.Device.Idiom == TargetIdiom.Unsupported)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // etc
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // etc
? ? ? ? ? ? }</span>
?這個方式除了在代碼也可以在XAML
<span style="font-size:12px;">? ?
<OnIdiom x:TypeArguments="View">
? ? ? <OnIdiom.Phone>
? ? ? <Grid>
? ? ? ? ? <Label Text="Phone content view" />
? ? ? ? </Grid>
? ? ? </OnIdiom.Phone>
? ? ? <OnIdiom.Tablet>
? ? ? ? <Grid>
? ? ? ? ? <Label Text="Tablet content view" />
? ? ? ? </Grid>
? ? ? </OnIdiom.Tablet>
? ? </OnIdiom></span>
? 3. 用DependencyService,在通過公用層生成接口,再在不同平臺上實現。這是在Xamarin中最常用的方法,
? ? ? ??
? ? ? 回到封裝庫,首先要定下一個目標就是做個.NET Standard的庫,而不再是做PCL. 還有做這種通用庫更應該考慮兼容多平臺,如iOS/Android/UWP等。以往的做法你可能需要搭建很多的目錄,然后去繼承一個公共接口去完成。現在通過MSBuild.Sdk.Extras(點擊查看), 通過MSBuild可以對不同平臺進行快速編譯,生成跨平臺的庫。參考Xamarin.Essentials(點擊進入),我自己開始編寫一個簡單的庫。先看看實現原理(如圖)? ? ? ?
? ? ? ?在.NET Standard 項目中你可以針對不同平臺進行編譯,利用第三方的MSBuild.Sdk.Extras進行不同平臺庫的生成工作,在這種方法上你不再需要上面提到的宏定義或Dependency Service,只需要針對預先設置好的文件進行跨平臺編譯,這大大方便了代碼的管理和維護。xx.standard.cs是一個公用的文件,相當于為不同平臺定義了一個接口,而具體實現放到各自平臺上如xx.ios.cs , xx.android.cs ..... 最后通過shared封裝公共方法暴露給不同項目訪問。
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
? <PropertyGroup>
? ? <!--Work around so the conditions work below-->
? ? <TargetFrameworks>netstandard1.0;netstandard2.0;Xamarin.iOS10;MonoAndroid71;</TargetFrameworks>
? ? <Product>$(AssemblyName)($(TargetFramework))</Product>
? ? <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
? ? <EnableDefaultItems>false</EnableDefaultItems>
? ? <BuildOutputTargetFolder>$(TargetFramework)</BuildOutputTargetFolder>
? </PropertyGroup>
? ?<PropertyGroup Condition=" '$(Configuration)'=='Debug' ">
? ? <DebugType>full</DebugType>
? ? <DebugSymbols>true</DebugSymbols>
? </PropertyGroup>
? <PropertyGroup Condition=" '$(Configuration)'=='Release' ">
? ? <DebugType>pdbonly</DebugType>
? </PropertyGroup>??
? <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
? ? <OutputPath>bin\Debug\$(TargetFramework)</OutputPath>
? </PropertyGroup>
? <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
? ? <OutputPath>bin\Release\$(TargetFramework)</OutputPath>
? </PropertyGroup>
? <ItemGroup>
? ? <PackageReference Include="MSBuild.Sdk.Extras" Version="1.4.0" PrivateAssets="All" />
? ? <Compile Include="**\*.shared.cs" />
? </ItemGroup>
? <ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard'))">
? ? <Reference Include="System.Numerics" />
? ? <Reference Include="System.Numerics.Vectors" />
? ? <Compile Include="**\*.netstandard.cs" />
? </ItemGroup>
? <ItemGroup Condition=" $(TargetFramework.StartsWith('MonoAndroid'))">
? ? <PackageReference Include="Xamarin.Android.Support.CustomTabs" Version="25.4.0.2" />
? ? <PackageReference Include="Xamarin.Android.Support.Core.Utils" Version="25.4.0.2" />
? ? <Reference Include="Mono.Android" />
? ? <Reference Include="System.Numerics" />
? ? <Reference Include="System.Numerics.Vectors" />
? ? <Compile Include="**\*.android.cs" />
? </ItemGroup>
? <ItemGroup Condition=" $(TargetFramework.StartsWith('Xamarin.iOS'))">
? ? <Reference Include="System.Numerics" />
? ? <Reference Include="System.Numerics.Vectors" />
? ? <Compile Include="**\*.ios.cs" />
? </ItemGroup>
? <Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
? <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
?剩下的事情,就是針對不同平臺作定義了
? ? ? 如Kinfey.ios.cs
using System;
namespace DNDemo.Lib
{
? ? public static partial class Kinfey
? ? {
? ? ? ? internal static string Check(){
? ? ? ? ? ? return "iOS";
? ? ? ? }
? ? }
}
?如Kinfey.android.cs
using System;
namespace DNDemo.Lib
{
? ? public static partial class Kinfey
? ? {
? ? ? ? internal static string Check()
? ? ? ? {
? ? ? ? ? ? return "Android";
? ? ? ? }
? ? }
}
而Kinfey.netstandard.cs
using System;
namespace DNDemo.Lib
{
? ? public static partial class Kinfey
? ? {
? ? ? ? internal static string Check() => throw new NotImplementedException();
? ? }
}
最后暴露的接口在Kinfey.shared.cs
using System;
namespace DNDemo.Lib
{
? ? public static partial class Kinfey
? ? {
? ? ? ? public static string CheckInfo(){
? ? ? ? ? ? return Check();
? ? ? ? }
? ? }
}
這樣你就可以進行編譯了,在Windows上你直接用Visual Studio 編譯即可,在macOS上你需要編譯就需要用命令行了(請高人指點下,我不知道為啥VS for mac不能build跨平臺的.NET Stanard......),首先你得restore , 接著執行
msbuild DNDemo.Lib.csproj /p:Configuration=Debug
這個時候,你就會得到四個庫.net standard 1.0 / .net standard 2.0 / ios / android 。找個項目調用一下,結果如下:
? ? ???
? ? ? 贈送源碼一份:(點擊下載)
? ? ? 最后Xamarin的第三方庫在國外有不少,但國內還是相對較少,希望各位愛好者都貢獻一下,為這個技術落地貢獻一份力量。
原文地址: https://blog.csdn.net/kinfey/article/details/80218291
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的从Xamarin.Essentials谈Xamarin库的封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你关心才值得分享 | K8S网络安全之访
- 下一篇: 用ASP.NET Core 2.0 建立