衆所周知,Xamarin應該是.net下的跨平臺開發工具。2016年以前還處於收費狀態,後被微軟收購後開源。但彷佛有個現象,開源後的Xamarin發展彷佛有些停滯,並且維護Xamarin的團隊又很執拗不肯變通。社區屢次建議UI層應該統一繪圖引擎,而不是映射原生控件。Xamarin.Forms給人的感受就是性能差,動畫僵硬,效果很差實現。以致於谷歌的Flutter火爆以後,Xamarin社區不少人便轉移陣地,你在百度搜索Xamarin,第一個關鍵詞就是xamarin還有人用麼。那麼對於C#/.net開發者來講,惟一的問題就是界面,就有了開源項目Xamarin.Flutter,但過完年沒多久,項目就Archived了,adamped說僅靠他和幾個開發人員的業餘時間很難搞定。但技術上確實可行,由於Skia在.net下原本就有綁定SkiaSharp,而Flutter底層便使用的Skia引擎。UIWidgets就是在Unity3D下的Flutter實現。那對於咱們.net開發者有沒有一種可能就是界面使用Flutter,業務邏輯採用C#呢,答案是可行的,請看以下分解。java
爲了可以使用Flutter調用C#,須要以下工具和環境android
前面四項不在贅述,請參考官方文檔,確保Flutter,Xamarin能夠運行項目,Android ndk請使用r15c版本,目前好像僅支持r15c,其餘未測試。ios
Embeddinator-4000是將C#轉化爲各平臺本機代碼的工具,可使用Nuget安裝git
Install-Package Embeddinator-4000 -Version 0.4.0
github
將工具路徑添加到系統環境PATH,建議添加nuget的全局緩存,相似C:\Users\Administrator\.nuget\packages\embeddinator-4000\0.4.0\tools
windows
若是工具使用出錯,請檢查sdk,或ndk版本,並確認Xamarin設置sdk,ndk路徑正確。並將以下信息添加進註冊表緩存
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Novell] [HKEY_CURRENT_USER\Software\Novell\Mono for Android] "AndroidNdkDirectory"="C:\\Program Files (x86)\\Android\\android-sdk\\ndk-bundle" "AndroidSdkDirectory"="C:\\Program Files (x86)\\Android\\android-sdk" "JavaSdkDirectory"="C:\\Program Files\\Android\\jdk\\microsoft_dist_openjdk_1.8.0.25\\"`
由於目前visualstudio的註冊表信息都是獨立文件形式,這多是工具自己的BUG,參考https://github.com/mono/Embeddinator-4000/issues/707async
這裏咱們先建立一個類庫,咱們使用Android Class Lib,若是不是Android 的方法,也能夠建立普通的類庫工具
編譯後獲得Test4Flutter.dll, 運行以下命令性能
Embeddinator-4000.exe --gen=java -out=test .\Test4Flutter.dll -p=Android -c
出現MSBUILD : error MSB1008: 只能指定一個項目。請確保路徑下沒有空格,或者複製dll到其餘路徑重試
在test目錄下咱們獲得一個Test4Flutter.aar文件
Android 裏添加Module,具體參考文檔,將Module添加進依賴。
public void onMethodCall(MethodCall call, Result result) { if (call.method.equals("getPlatformVersion")) { result.success("Android " + android.os.Build.VERSION.RELEASE); } else if (call.method.equals("getHelloString")){ result.success(test.getHelloString()); } else if(call.method.equals("add")){ result.success(test.add((int)call.argument("x"),(int)call.argument("y"))); } else { result.notImplemented(); } } static Future<String> getHelloString() async { return await _channel.invokeMethod('getHelloString'); } static Future<int> add(int x,int y) async{ final int ret = await _channel.invokeMethod('add',<String, dynamic>{ 'x': x, 'y': y, }); return ret; }
example內調用測試
調用方法時控制檯會打印以下
I/mono-stdout( 5946): call net function ->GetHelloString I/mono-stdout( 5946): call net function ->Add I/mono-stdout( 5946): call net function ->Add
不少時候咱們應該摒棄語言之爭,語言並沒有好壞,甚至能夠將其融合。