注意:我主要是在这里发布这个问题,以便将谷歌编入索引并让一些贫穷的灵魂陷入深陷这个混乱的麻烦,但却发现这不是他们自己的错。这个问题的一个可接受的答案是我可以使用的解决方法或Xamarin / SimpleJson的某人,这是一个错误,它将被修复。
我已经成功使用Xamarin.InAppBilling超过一年了(在真正的Google Play商店购买正常工作)。我们最近开始重新测试此功能(由于重构)并在查询我们的产品库存时遇到此异常(即使使用静态响应测试产品Skus):
Error Available Inventory: System.NullReferenceException: Object reference not set to an instance of an object
at Xamarin.InAppBilling.PocoJsonSerializerStrategy.DeserializeObject (System.Object value, System.Type type) [0x0047a] in <filename unknown>:0
at Xamarin.InAppBilling.SimpleJson.DeserializeObject (System.String json, System.Type type, IJsonSerializerStrategy jsonSerializerStrategy) [0x0003d] in <filename unknown>:0
at Xamarin.InAppBilling.SimpleJson.DeserializeObject[T] (System.String json) [0x00000] in <filename unknown>:0
at System.Linq.Enumerable+WhereSelectEnumerableIterator`2[TSource,TResult].MoveNext () [0x00064] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:285
at System.Collections.Generic.List`1[T]..ctor (IEnumerable`1 collection) [0x0008b] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/external/referencesource/mscorlib/system/collections/generic/list.cs:105
at System.Linq.Enumerable.ToList[TSource] (IEnumerable`1 source) [0x00011] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:835
at Xamarin.InAppBilling.InAppBillingHandler+<QueryInventoryAsync>c__AnonStorey0.<>m__0 () [0x00092] in <filename unknown>:0
我已经撤消了Xamarin的In App Billing代码,尤其是Xamarin.InAppBilling.InAppBillingHandler.QueryInventoryAsync(IList<string> skuList, string itemType)
方法。
它的作用是查询Google Play结算API以获取sku详细信息,然后反序列化返回的DETAILS_LIST
json对象。这是代码抛出NullReferenceException
的地方。所有这些都超出了我的控制范围,因此我使用了此代码的修改后的副本来获取原始json,当然它对我来说非常好看。代码:
var service = _serviceConnection.Service;
Task.Factory.StartNew<IList<Product>>( () => {
IList<Product> result;
try
{
Bundle bundle = new Bundle();
bundle.PutStringArrayList( "ITEM_ID_LIST", skus );
Bundle skuDetails = service.GetSkuDetails( 3, this.Activity.PackageName, ItemType.Product, bundle );
int responseCode = skuDetails.GetInt( "RESPONSE_CODE" );
if (responseCode != 0)
{
ViewModel.ShowTransactionError( "Error querying inventory: " + TranslateResponseCode( responseCode ) );
result = null;
}
else
{
IList<string> stringArrayList = skuDetails.GetStringArrayList( "DETAILS_LIST" );
result = null;
if (stringArrayList != null)
{
Console.WriteLine("DETAILS_LIST: " + string.Join("\n - ", stringArrayList));
result = stringArrayList.Select(x => JsonConvert.DeserializeObject<Product>(x)).ToList();
}
}
} catch (Exception ex)
{
ViewModel.ShowTransactionError( "Error querying inventory: " + ex.ToString() );
result = null;
}
return result;
} )
JSON:
DETAILS_LIST: {"title":"Sample Title","price":"0,93 €","type":"inapp","description":"Sample description for product: android.test.canceled.","price_amount_micros":933038,"price_currency_code":"EUR","productId":"android.test.canceled"}
- {"title":"Sample Title","price":"0,93 €","type":"inapp","description":"Sample description for product: android.test.item_unavailable.","price_amount_micros":933038,"price_currency_code":"EUR","productId":"android.test.item_unavailable"}
- {"title":"Sample Title","price":"0,93 €","type":"inapp","description":"Sample description for product: android.test.purchased.","price_amount_micros":933038,"price_currency_code":"EUR","productId":"android.test.purchased"}
- {"title":"Sample Title","price":"0,93 €","type":"inapp","description":"Sample description for product: android.test.refunded.","price_amount_micros":933038,"price_currency_code":"EUR","productId":"android.test.refunded"}
- {"title":"Boat Upgrade (Rowing in Motion - Solo)","price":"69,90 €","type":"inapp","description":"Analyze and Record an unlimited number of strokes per rowing session.","price_amount_micros":69900000,"price_currency_code":"EUR","productId":"com.rowinginmotion.mobile.boatapp.droid.solo.boat"}
- {"title":"Coach Upgrade (Rowing in Motion - Solo)","price":"98,77 €","type":"inapp","description":"Receive unlimited live data from a boat using a mobile WiFi.","price_amount_micros":98770000,"price_currency_code":"EUR","productId":"com.rowinginmotion.mobile.boatapp.droid.solo.coach"}
所以我认为SimpleJson / PocoJson在那里有任何串行器都有问题。看起来像是图书馆中的一个错误,而不是我身边的错误(通过他们的核对清单和所有在这里看上帝的工作)。
我使用JSON.NET问题是他们的Product
类显然没有默认构造函数(什么?!,我已经和IL一起工作了很多年而从未见过喜欢这个的东西),但有一个CompilerGeneratedAttribute
坚持下去。我的产品需要是该类的实例,以便我可以将它们传递回API ...
答案 0 :(得分:2)
linker再次点击。 PocoJsonSerializerStrategy
使用了大量的反射,所以这是我的第二次猜测,经过things you need to get right for IAPs to work的长列表。
将此添加到您的.csproj
,您就可以开始了。
<AndroidLinkSkip>Xamarin.InAppBilling</AndroidLinkSkip>
令人失望的是,Xamarin并没有让他们自己的库链接器证明......
这个问题很容易花费我一两天的时间,特别是因为有很多subtle ways,其中In-App-Billing会破坏你应该首先检查(特别是我们移动了很多IAP)从一个Activity到一个Fragment的逻辑,所以这也必须进行测试)。
旁注:我等待3x2h是徒劳的,因为我的测试设备上可以使用我的仪表化版本的Google Play Alpha频道更新。对于 me ,我可以使用从Xamarin Studio(甚至是Debug版本)部署的版本成功测试和运行IAP。这并不意味着这对你也有用。