藉助於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最新課程