问题描述
我正在使用亚马逊团队为 Xamarin.Android 项目提供的 AmazonIapV2Android.dll。我去年已经实现了它,并且已经成功地与 Dx+proguard 一起使用,使用如下的 proguard 规则。亚马逊文档也建议了这些行。请参阅link
-dontwarn com.amazon.**
-keep class com.amazon.** {*;}
-keepattributes *Annotation*
最近我使用相同的 proguard 文件使用 d8+r8 更改了我的 xamarin.android 项目。一切,谷歌 iap 实现也很好,但亚马逊 IAP 开始抛出异常。
Jsonable.CheckForErrors (System.Collections.Generic.Dictionary`2[TKey,TValue] jsonMap) com.amazon.device.iap.cpt.AmazonException: java.lang.RuntimeException: 缺少类型参数。
在 com.amazon.device.iap.cpt.RequestOutput.CreateFromJson (System.String jsonMessage) [0x0002d] 中 :0 \n 在 com.amazon.device.iap.cpt.AmazonIapV2Impl+AmazonIapV2Base.GetProductData (com.amazon.device.iap.cpt.SkusInput skusInput) [0x00013] in
我也使用链接器作为用户和 sdk 程序集,这显然会触发混淆,链接器删除了一些方法,因为仅使用 Sdk 程序集或不使用链接,一切正常。
我已将 AmazonIapV2Android
添加为要跳过的链接器,但没有帮助。
当我检查 RequestOutput.CreateFromJson 函数实现的代码实现时,如下所示。
using com.amazon.device.iap.cpt.json;
namespace com.amazon.device.iap.cpt
{
public sealed class RequestOutput : Jsonable
{
public string RequestId{get;set;}
public static RequestOutput CreateFromJson(string jsonMessage)
{
try
{
Dictionary<string,object> jsonMap = Json.Deserialize(jsonMessage) as Dictionary<string,object>;
Jsonable.CheckForErrors(jsonMap);
return CreateFromDictionary(jsonMap);
}
catch(System.ApplicationException ex)
{
throw new AmazonException("Error encountered while Unjsoning",ex);
}
}
在 dll 中对 Jsonable 的实现如下
namespace com.amazon.device.iap.cpt
{
public abstract class Jsonable
{
public static Dictionary<string,object> unrollObjectIntoMap<T>(Dictionary<string,T> obj) where T:Jsonable
{
Dictionary<string,object> jsonableDict = new Dictionary<string,object>();
foreach (var entry in obj)
{
jsonableDict.Add (entry.Key,((Jsonable)entry.Value).GetobjectDictionary());
}
return jsonableDict;
}
public static List<object> unrollObjectIntoList<T>(List<T> obj) where T:Jsonable
{
List<object> jsonableList = new List<object>();
foreach (Jsonable entry in obj)
{
jsonableList.Add(entry.GetobjectDictionary());
}
return jsonableList;
}
public abstract Dictionary<string,object> GetobjectDictionary();
public static void CheckForErrors(Dictionary<string,object> jsonMap)
{
object error;
if (jsonMap.TryGetValue("error",out error))
{
throw new AmazonException(error as string);
}
}
}
}
我也尝试将 linker.xml 与如下设置一起使用,但也无济于事。
<assembly fullname="AmazonIapV2Android">
<namespace fullname="com.amazon.device.iap.cpt" />
<namespace fullname="com.amazon.device.iap.cpt.log" />
<namespace fullname="com.amazon.device.iap.cpt.json" />
</assembly>
当我为以 com.amazon
前缀开头的命名空间下的所有方法和成员定义 keepclass 时,我无法弄清楚为什么要抛出异常。
知道这可能是什么原因吗?
编辑:刚刚进行了几次测试,我的初始评论有点错误。奇怪的方式应用程序正在使用链接器设置“仅 SDK 程序集”进行调试,但在发布时,即使使用“仅 SDK 程序集”也无法正常工作
解决方法
显然,这是使用 R8 和 Amazon IAP 的已知问题。典型的亚马逊不关心和更新他们的包裹。特别是自 2016 年以来 Xamarin IAP 没有更新。 这是问题的链接 https://forums.developer.amazon.com/questions/205480/in-app-billing-not-working-since-android-studio-de.html
https://issuetracker.google.com/issues/134766810
目前有 3 种解决方法,
- 禁用 r8。不好的是没有混淆,没有优化。
- 使用 dx+proguard+multi dex 代替 d8+r8。这里有问题,如果你使用 androidx,androidx 库不支持 dx+proguard,它们只支持 d8+r8,你需要返回支持库。
- 我不确定,但亚马逊 website 声称它已声明,它适用于 r8,但这可能适用于 android java 库而不适用于 xamarin。因为当我检查时,jar 有更新的版本。理论上您可以使用绑定库来获取新的 dll 并尝试,但我什至为 Android Studio 项目阅读,这不起作用。所以我尝试创建一个绑定库,但它有很多错误,而且 api 似乎与 xamarin 不同。对于非盈利的应用商店来说,这是一个很大的努力。 这里也是 xamarin.android 上的 github issue 链接。