趁着失業了,閒着沒事兒學習了下Xamarin.Android binding,在以往的開發中,我相信不少人都遇到過binding的坑,也不例外,php
在作這個工做前,我上網搜索了一下關於binding的文章,也有,可是比較少,並且文章都是一兩年前,不少SDK都更新了不少代了,java
按照他們以前的一些作法就會有問題。node
我嘗試綁定了微信SDK、支付寶SDK、百度地圖SDK,在大神幫助下,一步一步綁定成功了。android
並且我相信這幾個SDK在開發中用到的機率也仍是很大的,因此特此分享下綁定遇到的坑,也爲了更好的記錄本身遇到的問題。git
話很少說,直接上代碼。github
1.準備工做:下載百度android開發包,畢竟工欲善其事必先利其器,地址:http://lbsyun.baidu.com/sdk/download?selected=mapsdk_basicmap,mapsdk_searchfunction,mapsdk_lbscloudsearch,mapsdk_calculationtoolapi
2.開發環境,這裏就不講解開發環境搭建了。我這兒的環境的是VS2017+win10,後續的兩個綁定都是如此。瀏覽器
3.Binding:微信
3.1 新建安卓bingding工程
3.2 將下載的壓縮包解壓,而後把裏面的jar包以及so文件放到如下目錄
這裏的so文件就是爲不一樣的cup架構提供的指令集
3.3 接下來就是設置jar、so文件的屬性,按照以下設置
3.4接下來就是編譯,不出意外會出現如下錯誤
錯誤的意思就是字段名稱和類名重複了才致使編譯不過,那麼接下來怎麼辦呢,這就須要咱們手動配置這些字段名稱,畢竟VS再智能也會有綁定不對的時候啊!
打開文件Metadata.xml文件,加入如下代碼。
<attr path="/api/package[@name='com.baidu.location']/class[@name='Address']/field[@name='address']" name="name">AddressInfo</attr> <attr path="/api/package[@name='com.baidu.mapapi']/class[@name='VersionInfo']/field[@name='VERSION_INFO']" name="name">VersionInformation</attr> <attr path="/api/package[@name='com.baidu.platform.comapi.map']/class[@name='B']/field[@name='b']" name="name">BField</attr> <attr path="/api/package[@name='com.baidu.platform.comapi.map']/class[@name='E']/field[@name='e']" name="name">EField</attr>
這裏的意思呢就是講這些字段名稱重命名,Metadata.xml還能夠去除某些類或字段,設置某些函數的返回值之類的。Metadata.xml更多的用法的話,能夠參考https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/customizing-bindings/java-bindings-metadata/。主要全是英文,我英文能力也差,估計翻譯出來你們都會吐槽,還不如本身看。
而後再編譯就沒有問題了,說一下,百度地圖我編譯的環境是在jdk1.8+安卓目標平臺7.0下編譯的。
而後我照着百度地圖提供的DEMO寫了個示例
關鍵代碼:
SDKInitializer.Initialize(ApplicationContext); SetContentView(Resource.Layout.Main); mapView = FindViewById<MapView>(Resource.Id.mapView); currentLocationMode = LocationMode.Normal; var baiduMap = mapView.Map; //定義Maker座標點 LatLng point = new LatLng(30.691359, 104.052236); //構建Marker圖標 BitmapDescriptor bitmap = BitmapDescriptorFactory.FromResource(Resource.Drawable.marker); //構建MarkerOption,用於在地圖上添加Marker OverlayOptions option = new MarkerOptions().InvokePosition(point).InvokeIcon(bitmap); //在地圖上添加Marker,並顯示 baiduMap.AddOverlay(option); baiduMap.MyLocationEnabled = true;更多的用法的話,參照百度地圖的API
代碼的話,別急,會在最後給出GITHub的地址。
效果圖:
在調用百度地圖的時候,須要配置你的APK簽名的sha1值,調試的時候呢,都是用的這個目錄下的 C:\Users\HuShuai\AppData\Local\Xamarin\Mono for Android
debug.keystore來簽名的,而後須要獲取它的sha1值,推薦一個好用的工具,並且很是簡單的,詳情請看: http://bbs.lbsyun.baidu.com/forum.php?mod=viewthread&tid=106461&qq-pf-to=pcqq.group.
能夠經過命令行來獲取 Keytool -list -v -keystore "C:\Users\用戶名\AppData\Local\Xamarin\Mono for Android\debug.keystore" -alias androiddebugkey -storepass android -keypass android。
可是這個有時候好像不太管用, 好比我就沒有獲取到,不如第一種方式簡單暴力。
有了前面的百度地圖綁定示例,後面的兩個綁定基本都相似了,無非就是修修改改編譯不過的問題。
SDK下載地址:https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1
But支付寶稍微有點兒不同:
一開始編譯的話,應該會提示如下錯誤
所有提示不能強制轉換類RpcException爲java.lang.object
按照上一個綁定的經驗來綁定的話,徹底懵逼了,根本無法弄。But能夠這樣
將轉換的地方,直接修改爲 this.Handle
相似下面這樣
接下來就是把裏面轉換的地方都改完,而後把裏面的內容所有複製,新建一個名字爲RpcException的類
而後把內容粘貼進去,新建的類放在 Additions 這個文件夾中。
而後就是在Metadata.xml裏面加入一下代碼
<remove-node path="/api/package[@name='com.alipay.android.phone.mrpc.core']/class[@name='RpcException']" />這裏的意思呢就是刪除banding自動給咱們生成的類,而咱們的 Additions 文件夾呢則是存放用戶自定義的內容,在編譯的時候則會把咱們添加的內容一塊兒編譯進去。
而後就是本身寫了一個支付demo,只能跳轉到支付界面以及調用H5頁面支付界面,沒有測試是否可以真的支付成功,主要是沒有若是要測試的話,還須要部署套測試環境才行。若是那位測試能夠支付的話,請給博主留言,謝謝了。
調用H5支付頁面的話,須要在AndroidManifest.xml文件中加入如下節點:
<activity android:name="com.alipay.sdk.app.H5PayActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind"></activity> <activity android:name="com.alipay.sdk.auth.AuthActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind"></activity>效果圖:
微信SDK下載地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
仍是按照以前的操做,將jar文件複製到 Jars 文件夾裏,設置編譯屬性爲 EmbeddedJar
這裏呢說一下博主在綁定過程當中 遇到的坑:
一開始編譯的時候,提示名稱重複,我心想so easy,這難道不我啊,畢竟有兩個綁定的經驗了,而後就再Metadata.xml添加了以下兩句代碼:
<attr path="/api/package[@name='com.tencent.mm.opensdk.modelbase']/class[@name='BaseResp']/field[@name='errCode']" name="managedName">errCode</attr> <attr path="/api/package[@name='com.tencent.mm.opensdk.modelmsg']/class[@name='WXMediaMessage']/field[@name='mediaObject']" name="managedName">mediaObject</attr>
並且也如預期同樣編譯成功了,心想這不是多難啊。而後就想照着這個 文章 這樣寫個支付Demo,寫着寫着,準備用到 PayReq 這個類的時候,結果發現如何引用都找不到它,這就尷尬了。
我反編譯看了下微信SDK源碼,
我發現是有這個類的,可是爲何綁定沒有呢? 我又在綁定項目工程下的目錄去查看了生成的類文件,結果也沒有叫作 PayReq 的類
What ? 這咋辦呢,而後看了下警告信息,發現是這個類不能正確映射,而後就缺失了,可是這咋辦呢?翻了一下午的Xamarin論壇,又全是英文,也沒有找到什麼有效的解決辦法,But 我最前面說認識了個大佬啊,不懂就請教啊。
大佬告訴我你這錯誤緣由多是 JDK版本 設置的太高的緣由,讓我改爲 JDK1.7,目標編譯框架設置成6.0試試
大佬就是大佬,一針見血的找到問題,剩下的就是兩個小問題,重命名就搞定了,到此編譯成功!
<attr path="/api/package[@name='com.tencent.mm.opensdk.modelbase']/class[@name='BaseResp']/field[@name='errCode']" name="managedName">errCode</attr> <attr path="/api/package[@name='com.tencent.mm.opensdk.modelmsg']/class[@name='WXMediaMessage']/field[@name='mediaObject']" name="managedName">mediaObject</attr>
可是又遇到一個奇葩問題,在實例化 PayReq 對象時,VS仍是找不到這個類,我用ILSpay看了生成的類,是有這個的 !
But並不能影響什麼,由於仍是能夠編譯成功!!!
並且若是我將編譯好的dll 文件單獨放到 安卓工程裏面去引用的話,編譯是沒有問題的,這個時候VS也能知道這個類,在對象瀏覽器中也能看到這個類,我試過將兩個工程裏面的obj、bin目錄下的文件都刪除,而後從新編譯,結果仍是這個問題,直接引用這個binding工程找不到PayReq這個類,可是卻能編譯成功。不知道是否是VS17的一個Bug,若是那位園友遇到過這個問題,也能夠留言說一下。
微信支付後回調Activity 代碼:
using System; using Android.App; using Android.Content; using Android.OS; using Com.Tencent.MM.Opensdk.Modelbase; using Com.Tencent.MM.Opensdk.Openapi; using Android.Util; using Android.Widget; using Com.Tencent.MM.Opensdk.Constants; namespace XamarinWeiXinDemo { /// <summary> /// 微信支付回調Activity /// </summary> public class WXPayEntryActivity : Activity, IWXAPIEventHandler { private IWXAPI api; public void onCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); //SetContentView(R.layout.pay_result); //佈局是能夠自定義 api = WXAPIFactory.CreateWXAPI(this, "App_ID"); api.HandleIntent(Intent, this); } protected override void OnNewIntent(Intent intent) { base.OnNewIntent(intent); Intent = intent; api.HandleIntent(intent, this); } public void OnReq(BaseReq p0) { } public void OnResp(BaseResp p0) { Log.Debug("微信支付回調", "onPayFinish, errCode = " + p0.errCode); if (p0.Type == ConstantsAPI.CommandPayByWx) { //0 成功 展現成功頁面 //-1 錯誤 可能的緣由:簽名錯誤、未註冊APPID、項目設置APPID不正確、註冊的APPID與設置的不匹配、其餘異常等。 //-2 用戶取消 無需處理。發生場景:用戶不支付了,點擊取消,返回APP。 if (p0.errCode == 0) { //支付成功邏輯 Toast.MakeText(this, "支付成功", ToastLength.Long).Show(); } else { //支付失敗 Toast.MakeText(this, "支付失敗", ToastLength.Long).Show(); } Finish(); } } } }
三個綁定demo都已經傳至GitHub
百度地圖:https://github.com/HuUncle/Xamarin.Android-BaiDuMapSDKBinding
微信:https://github.com/HuUncle/Xamarin.Android-WeiXinSDKBindingDemo
支付寶:https://github.com/HuUncle/Xamarin.Android-AlipaySDKBindingDemo
若是以爲對你有幫助,請幫我點個贊,你的推薦是我學習的動力。
轉載請註明出處 IT胡小帥: http://www.cnblogs.com/CallMeUncle/p/6562440.html