概述
上一篇 C#移動跨平臺開發(1)環境準備發布之后不久,無獨有偶,微軟宣布了開放.NET框架源代碼并且會為Windows、Mac和Linux開發一個核心運行時(Core CLR),這也是開源的!IT媒體網站紛紛轉載,博客園的C#開發者們熱淚盈眶(泥煤都等這一天好久了!)
與此同時VS2015預覽版更是直接集成了Android模擬器,但是其實里面并沒有說集成IOS模擬器,我不知道大家是怎么得出可以直接用VS來開發Android和IOS應用的。不管怎么說,這都是個好消息。那么問題來了,C#如何來開發Android和IOS應用?微軟會怎么做我們不確定,但是我們倒是可以來看看Xamarin是如何做的。
Android系統架構
我想下面這張圖做Android開發的同學應該很熟悉,下面我們就通過來了解Android系統的架構入門來看看Xamarin會怎么樣去做?
- Linux Kernel 操作系統層
- Libraries And Android Runtime 各種庫和Android 運行環境
- Application Framework 應用框架層 (由Java編寫)
- Applications 應用程序層(由Java編寫并且在Dalvk虛擬機來運行)
現在做Android開發的同學只要熟悉這些應用框架層的一些接口和類庫就可以給方便的來實現自己的Android應用程序。
關于Dalvk虛擬機與Java運行環境的區別
- Dalvik主要是完成對象生命周期管理,堆棧管理,線程管理,安全和異常管理,以及垃圾回收等等重要功能。
- Dalvik負責進程隔離和線程管理,每一個Android應用在底層都會對應一個獨立的Dalvik虛擬機實例,其代碼在虛擬機的解釋下得以執行。
- 不同于Java虛擬機運行java字節碼,Dalvik虛擬機運行的是其專有的文件格式
- Dex文件格式可以減少整體文件尺寸,提高I/o操作的類查找速度。
- 是為了在運行過程中進一步提高性能,對dex文件的進一步優化。
- 所有的Android應用的線程都對應一個Linux線程,虛擬機因而可以更多的依賴操作系統的線程調度和管理機制
- 有一個特殊的虛擬機進程Zygote,他是虛擬機實例的孵化器。它在系統啟動的時候就會產生,它會完成虛擬機的初始化,庫的加載,預制類庫和初始化的操作。如果系統需要一個新的虛擬機實例,它會迅速復制自身,以最快的數據提供給系統。對于一些只讀的系統庫,所有虛擬機實例都和Zygote共享一塊內存區域。
大家注意第2點和第7點有助于我們理解Xamarin.Android的工作機制。
Xamarin.Android 架構
Java編寫的Android應用程序通過調用 Android.* 和 Java.* 這些命名空間下的類來實現一些系統的功能包括:聲音、顯示、OpenGl等一些通過Java API不能實現的功能或者說是與硬件、系統平臺相關的功能。那這里的問題是當我們用C#來編寫的時候,這些功能怎么去調用?C#寫的Android 應用程序又是如何初始化的?
Android Callable Wrappers (ACW)
當一個C#開發的Android程序運行的時候,除了一個Dalvik的虛擬機實例,還有一個Mono的虛擬機實例在運行。那個Dalvik虛擬機實體就像一個宿主,我們的APP在宿主上運行,而我們所有用C#寫的方法都會以ACW的形式被調用。在Java代碼中以native的式式invoke,就像invoke其它C或者C++的代碼一樣。
Momodroid.exe 在編譯階段會為我們的C#類生成對應的ACW。
1 using System; 2 using Android.App; 3 using Android.OS; 4 5 namespace Mono.Samples.HelloWorld 6 { 7 public class HelloAndroid : Activity 8 { 9 protected override void OnCreate (Bundle savedInstanceState) 10 { 11 base.OnCreate (savedInstanceState); 12 SetContentView (R.layout.main); 13 } 14 } 15 }
對應生成的ACW代碼:
1 package mono.samples.helloWorld; 2 3 public class HelloAndroid 4 extends android.app.Activity 5 { 6 static final String __md_methods; 7 static { 8 __md_methods = 9 "n_onCreate:(Landroid/os/Bundle;)V:GetOnCreate_Landroid_os_Bundle_Handler\n" + 10 ""; 11 mono.android.Runtime.register ("Mono.Samples.HelloWorld.HelloAndroid, HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", HelloAndroid.class, __md_methods); 12 } 13 14 public HelloAndroid () 15 { 16 super (); 17 if (getClass () == HelloAndroid.class) 18 mono.android.TypeManager.Activate ("Mono.Samples.HelloWorld.HelloAndroid, HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "", this, new java.lang.Object[] { }); 19 } 20 21 @Override 22 public void onCreate (android.os.Bundle p0) 23 { 24 n_onCreate (p0); 25 } 26 27 private native void n_onCreate (android.os.Bundle p0); 28 }
大家可以看到上面那個 native的n_onCreate方法最后就會調用那個通過mono虛擬機注冊的Mono.Samples.HelloWorld.OnCreate 方法。
Managed Callable Wrappers (MCW)
上面我們講Dalvik 虛擬機是我們C#開發的Android應用程序的宿主,它通過ACW來調用我們用C#寫的方法。如果我們的這個C#里面的方法涉及到一些聲音或者系統本身,或者說現在已經有很多成熟的用Java寫的類庫,我們想調用怎么辦? 答案是我們再通過MCW 調回去。在C#運行時中去調用Java 稱之為MCW。
Xamarin.Android Framework中有很多就是MCW,關于MCW的創建以及C#與Java集成開發的東西我們后面再細講,包括一個C#開發的Android應用程序是如何被啟動的,我們后面再細講。對于C#開發的Android應用程序來說,性能上面肯定是會有影響,但是影響有多大,我并沒有做過具體測試,所以就不詳述了。后面我們再細細的去對比。
Xamarin.IOS 架構
對于開發者來說,Xamarin.IOS相對于Xamarin.Android就要簡單很多了,我們用C#開發的ios應用程序在被編譯成IL代碼之后,然后轉交給Apple complier直接編譯成IPhonee的本地機器碼。也就是說C#寫的IPhone應用程序和objective-c 寫的是一樣的。并且Xamarin團隊保證在每一個IOS系統更新的時間同步更新Xamarin.IOS這樣我們就不用擔心被滯后了。
小結
這僅僅是一個粗略的介紹,Xamarin移動跨平臺方案是如何來工作的,還有太多我們沒有涉及。 Xamarn.Forms為多種移動平臺提供了統一的UI(雖然目前還有些比較特別的沒有實現,官方也沒有力推它,用來做一些原型,或者概念驗證可以試一樣,另外如果你的UI確實很簡單,那倒是沒有問題。),當然在Xamarin.Forms不能夠滿足你的要求的時候,可以使用Xamarin.Android和Xamarin.IOS的UI控件,這些也是Native的,也就是說在UI方面不會有性能的影響。
就目前來看C#來開發IOS應用更具有優越性,我們要在VS中開發Iphone的應用程序需要配一臺Mac來做編譯。相對而言,開發Android的應用程序就會顯得繁瑣一些,底下還有一些隱藏的東西我們沒有具體的講,包括一個app的創建過程,C#與Java集成在一起開發時候的交互等等,這些問題我們就留在后面慢慢來解決。
參考閱讀
http://developer.xamarin.com/guides/android/under_the_hood/architecture/
http://en.wikipedia.org/wiki/Java_Native_Interface
http://developer.xamarin.com/guides/android/advanced_topics/java_integration_overview/
文章列表