借助於Mono For Android技術,.Net開發者也可以使用自己熟悉的C#語言以及.Net來開發Android應用。由於Mono For Android把Android SDK中絕大部分類庫都已經實現,基本直接參考Java開發Android的書就可以掌握Mono for android技術。
對於有項目技術決策權的團隊,如果項目組成員對Java不熟悉,那么可以使用自己熟悉的.Net來開發Android應用,比如我的一個學生使用Mono For Android開發了一款應用(應學生要求,應用的名字保密),3月份一個月就入賬41萬元。當然是否賺錢和工具關系不大,這里貼出這個案例只是為了告訴大家:Mono For Android是可以完成你的需求的
有一個非常重要的問題,做Android開發的時候還會使用一些第三方的jar包。jar是java的技術,那么在Mono for android中需要怎樣使用這些jar呢? 需要一個把jar綁定到dll的過程。
下面以一個典型的Mono For android調用百度地圖sdk來講解一下這個過程:
第一步:創建jar的綁定程序集
Mono for android提供了Java Binding Library用來自動化的創建綁定(或者說包裝)jar的.Net程序集,這樣就可以通過調用程序集中的包裝類來調用jar中的類了。
首先從百度地圖網站上下載百度地圖的SDK;
接着在Visual Studio的點擊主菜單【文件】→【新建】→【項目】,在對話框中選擇Mono for Android下的“Java Binding Library”,給項目取一個名字,比如“BaiduMapSDK”;
接下來把baidumapapi_v2_1_1.jar放到Jars文件夾下,選中jar文件,在屬性視圖中將“生成操作”屬性設置為“EmbeddedJar”,生成解決方案。我們就會發現在bin/Debug文件夾下就生成了BaiduMapSDK.dll這個包裝程序集,細心的朋友應該發現了在obj\Debug\generated\src下生成的cs代碼就是對jar的封裝調用。
第二步:引用綁定程序集
點擊主菜單【文件】→【新建】→【項目】,在對話框中選擇Mono for Android下的“Android Application”創建一個Android項目,比如取名為“MapTest”。
在項目上點右鍵選擇【添加引用】→【項目】,在項目列表中選擇第一步創建的“BaiduMapSDK”。
如果是普通的全部都是用java代碼寫的jar,那么這樣就可以用了,但是百度地圖SDK中是包含使用C/C++寫的Native代碼(如果SDK包中除了jar文件之外還有.so文件,那么就說明有一部分代碼是非Java的Native代碼)的,因此還需要把libapp_BaiduMapApplib_v2_1_1.so、libvi_voslib.so這兩個庫文件放到MapTest項目中,並且把so文件的“生成操作”設置為“AndroidNativeLibrary”,否則運行的時候會提示加載不到Library。
在MapTest項目中創建一個libs文件夾,並且在libs文件夾下創建一個armeabi文件夾,然后把libapp_BaiduMapApplib_v2_1_1.so、libvi_voslib.so放到這個文件夾下。如果運行到armeabi-v7a CPU下,還需要同樣創建一份armeabi-v7a文件夾;同樣如果運行在x86CPU下則同樣需要創建x86文件夾(但是百度地圖SDK的so暫時不支持X86CPU)。
第三步:調用百度地圖SDK
在axml中添加地圖視圖控件:MapView
<com.baidu.mapapi.map.MapView android:id="@+id/bmapsView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
反編譯BaiduMapSDK.dll我們會發現,這個程序集中把命名空間、類名、方法名等都改成了.Net的命名規則,比如MapView類在java中的包名是com.baidu.mapapi.map,但是在dll程序集中命名空間變成了Com.Baidu.Mapapi.Map(首字母大寫)。
因為layout文件是給android引擎使用的,而程序集中的類只是對java類的的包裝,所以注意在layout文件中控件節點的命名空間要使用java中的命名規則com.baidu.mapapi.map.MapView,而不是Com.Baidu.Mapapi.Map.MapView。
在Activity的OnCreate中SetContentView之前添加下面的代碼來初始化百度地圖SDK,否則會報錯“com.baidu.platform.comjni.map.basemap.JNIBaseMap.Create”:
BMapManager mBMapMan = new BMapManager(this.Application);
mBMapMan.Init("我的Key", null);
注意把“我的Key”替換成從百度地圖網站上申請的應用Key。
當然還沒有結束,因為還需要增加百度地圖SDK需要的權限,至少添加如下的權限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
程序運行之后百度地圖就顯示出來了。
當然如果仔細查看生成的DLL,你可能會發現所有的方法的參數名字全部都是p0、p1、p2,而不是有意義的參數名。
這是怎么回事呢?不像.Net的MSIL中把參數名也寫入了IL代碼,Java中方法名是沒有寫入.class 的,因此工具也無法通過jar文件分析出參數的名字,所以“Java Binding Library”生成的程序集的方法的參數名都是p0、p1、p2這樣無意義的參數名,能否命名為有意義的參數名呢?關於這個問題可以參考官方文檔《Binding a Java Library (.jar),Consuming Java Libraries from C#》 中“Fixing Up Parameter Names”這段內容,里面提到了可以編輯Metadata.xml文件來為參數取名字。
但是這個為參數命名的過程很枯燥,按理來說,如果我們拿到了jar對應的java源文件,那么Mono For Android應該可以根據java源代碼來知道參數的名字,但是貌似這個還沒有實現。我有一個思路,使用Eclipse的JDT中的Java源碼分析類ASTParser(用法參考:http://lym6520.iteye.com/blog/747840 和http://blog.csdn.net/flying881114/article/details/6187503 )來分析jar對應的java源文件,然后自動生成Metadata.xml文件。工作很忙,暫時沒時間實現這個想法,希望有園子里的大牛能實現,造福廣大Monoer!
如鵬網.Net培訓班正在報名,有網絡的地方就可以參加如鵬網的學習,學完就能高薪就業,點擊此處了解
三年前只要懂“三層架構”就可以說“精通分層架構”;現在則需要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值錢;
三年前只要會SQLServer就可以說自己“精通數據庫開發”;現在則需還需要掌握MySQL等開源數據庫才能說是“.Net開源”時代的程序員;
三年前只要會進行用戶上傳內容的安全性處理即可;現在則需要熟悉雲存儲、CDN等才能在雲計算時代游刃有余;
三年前只要掌握Lucene.Net就會說自己“熟悉站內搜索引擎開發”;現在大家都用ElasticSearch了,你還用Lucene.Net就太老土了;
三年前發郵件還是用SmtpClient;現在做大型網站發郵件必須用雲郵件引擎;
三年前緩存就是Context.Cache;現在則是Redis、Memcached的天下;
如鵬網再次引領.Net社區技術潮流!點擊此處了解如鵬網.Net最新課程