前言

趁着失业了,闲着没事儿学习了下Xamarin.Android binding,在以往的开发中,我相信很多人都遇到过binding的坑,也不例外,

我也踩了很多雷,好在认识了个大佬,指导了很多 

在做这个工作前,我上网搜索了一下关于binding的文章,也有,但是比较少,而且文章都是一两年前,很多SDK都更新了很多代了,

按照他们之前的一些做法就会有问题。

我尝试绑定了微信SDK、支付宝SDK、百度地图SDK,在大神帮助下,一步一步绑定成功了。

而且我相信这几个SDK在开发中用到的概率也还是很大的,所以特此分享下绑定遇到的坑,也为了更好的记录自己遇到的问题。

话不多说,直接上代码。

百度地图SDK绑定

1.准备工作:下载百度android开发包,毕竟工欲善其事必先利其器,地址:http://lbsyun.baidu.com/sdk/download?selected=mapsdk_basicmap,mapsdk_searchfunction,mapsdk_lbscloudsearch,mapsdk_calculationtool

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绑定

有了前面的百度地图绑定示例,后面的两个绑定基本都类似了,无非就是修修改改编译不过的问题。

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绑定

微信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 == )
{
//支付成功逻辑
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

Xamarin.Android Binding篇的更多相关文章

  1. Xamarin Android组件篇教程RecylerView动画组件RecylerViewAnimators(1)

    Xamarin Android组件篇教程RecylerView动画组件RecylerViewAnimators(1) RecyclerView是比ListView和GridView更为强大的布局视图, ...

  2. Xamarin.Android Binding

    0.要绑定的jar库,需要保证编译jar使用的jdk版本,与绑定时xamarin使用的jdk版本一致. 查看编译jar的jdk版本的方法:jar解压后,a.看MANIFEST.MF  b. javap ...

  3. Xamarin Android 之起始篇

    序言: 在博客园注册了已经有2年多了,快三年了.从开始学习这一行开始就在博客园注册了这个账号.至今也还没有写过一篇随笔,大多时候都是在园子里头潜水,看大牛写的文章,学习. 写博客不为啥,就是自己对自己 ...

  4. Xamarin.Android和UWP之MVVM的简单使用(二)

    0x01 前言 前面一篇,Xamarin.Android和UWP之MVVM的简单使用(一),主要讲了MvvmLight的简单使用 这篇主要讲讲MvvmCross的简单使用,例子的话,还是和上篇的一样. ...

  5. Xamarin.Android和UWP之MVVM的简单使用(一)

    0x01 前言 就目前而言,MVVM可以说是挺流行的,无论是web端还是移动端,web端的主要代表angularjs,avalonjs等, 移动端(xamarin,uwp)的代表应该是mvvmligh ...

  6. JPush (极光推送) For Xamarin.Android

    官方教程上讲的是 GCM (Google Cloud Messaging) , 不过 GFW 是 GCM 过不去的坎. 极光推送 JPush 是国内的一个不错的替代方案. JPush 提供的 API ...

  7. Xamarin. Android实现下拉刷新功能

    PS:发现文章被其他网站或者博客抓取后发表为原创了,给图片加了个水印 下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. ...

  8. 跨过几个坑,终于完成了我的第一个Xamarin Android App!

    时间过得真快,距离上次发随笔又是一年多.作为上次发的我的第一个WP8.1应用总结的后继,这次同样的主要功能,改为实现安卓版APP.前几个月巨硬收购Xamarin,把Xamarin集成到VS里了,大大方 ...

  9. Xamarin.Android中使用ResideMenu实现侧滑菜单

    上次使用Xamarin.Android实现了一个比较常用的功能PullToRefresh,详情见:Xamarin. Android实现下拉刷新功能 这次将实现另外一个手机App中比较常用的功能:侧滑菜 ...

随机推荐

  1. Bootstrap入门(七)组件1:字体图标

    Bootstrap入门(七)组件1:字体图标   包括200个来自 Glyphicon Halflings 的字体图标,允许 Bootstrap 免费使用. 部分可用图标截图: 所有图标都需要一个基类 ...

  2. 基於tiny4412的Linux內核移植 --- 实例学习中断背后的知识(1)

    作者:彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台 tiny4412 ADK Linux-4.9 概述 前面几篇博文列举了在有设备树的时候,gpio中断的 ...

  3. 解决使用Idea/Eclipse编写Hadoop程序包依赖问题

    解决使用Idea/Eclipse编写Hadoop程序包依赖问题 解决包依赖的一种简单粗暴方法就是, 把下载下来的Hadoop压缩包解压, 搜索里面所有的额jar包文件,然后复制到一个目录,在使用Ide ...

  4. java_JDBC字段对应

    地址: http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/java.102/B19275-03/datacc.htm ...

  5. HUST 1586 数字排列

    1586 - 数字排列 时间限制:1秒 内存限制:128兆 91 次提交 36 次通过 题目描述 现有n个k位的数字,你的任务是重新安排数字每一位的位置,使得重新安排后这n个数字中最大的数字和最小的数 ...

  6. Swift 2.0 UItableView 的简单使用

    在IOS开发中,UItableView 的使用真的是最常见最普通的了,现在在自学swift 今天也是这用Swift 写了写 UItableview的使用,还有一些经常出错的地方.下面我先把整个控制器的 ...

  7. Struts2系列笔记(2)---Struts.XML

    Struts2.xml 本篇博客主要讲Struts2.xml中package下的标签和标签属性,主要分以下四个部分说明: (1)action的配置基本属性 (2)同一个Action类中不同方法满足不同 ...

  8. Spring DM所提供的Bundle监听接口OsgiBundleApplicationContextListener

    通过使用Spring DM提供的监听接口,我们可以更好的对服务进行管控,其实该接口也非常简单就能使用上,只要自定义一个类实现OsgiBundleApplicationContextListener接口 ...

  9. Java获取http和https协议返回的json数据

    现在很多公司都是将数据返回一个json,而且很多第三方接口都是返回json数据,而且还需要使用到http协议,http协议是属于为加密的协议,而https协议需要SSL证书,https是将用户返回的信 ...

  10. css控制图片与文字对齐

    文字旁边搭配图片时,发现图片比文字靠上,原来默认的情况是图片顶对齐而文字底对齐,通过设置css属性可以使得图片与文字对齐. 设置各对象的vertical-align属性,属性说明:baseline-将 ...