Ere*_*eza 29 android in-app-billing
我首次使用新的v3 API设置了In-App Billing.它在我的设备上正常工作,但我收到了很多其他用户的错误报告.
其中之一是:
java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: queryInventory
at my.package.util.iab.IabHelper.checkSetupDone(IabHelper.java:673)
at my.package.util.iab.IabHelper.queryInventory(IabHelper.java:462)
at my.package.util.iab.IabHelper$2.run(IabHelper.java:521)
at java.lang.Thread.run(Thread.java:1019)
Run Code Online (Sandbox Code Playgroud)
另一个是:
java.lang.NullPointerException
at my.package.activities.MainActivity$4.onIabSetupFinished(MainActivity.java:159)
at my.package.util.iab.IabHelper$1.onServiceConnected(IabHelper.java:242)
Run Code Online (Sandbox Code Playgroud)
我的活动实现遵循Google的示例代码(所有引用的类都不受示例影响):
IabHelper mHelper;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
mHelper = new IabHelper(this, IAB_PUBLIC_KEY);
mHelper.enableDebugLogging(true);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
return;
}
// Hooray, IAB is fully set up. Now, let's get an inventory of
// stuff we own.
mHelper.queryInventoryAsync(mGotInventoryListener); //***(1)***
}
});
}
// Listener that's called when we finish querying the items we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if (!result.isFailure()) {
if (inventory.hasPurchase(SoundsGlobals.IAB_SKU_PREMIUM)){
//we are premium, do things
}
}
else{
//oops
}
}
};
@Override
protected void onDestroy() {
if (mHelper != null) {
mHelper.dispose();
mHelper = null;
}
super.onDestroy();
}
Run Code Online (Sandbox Code Playgroud)
我假设两个错误都来自标记为的行 ***(1)***
这些错误的原因是什么?如果我queryInventoryAsync只在内部调用onIabSetupFinished,那么如何mHelper将null mHelper设置为null,或者不设置?
有谁知道解决这个问题?
Ere*_*eza 19
正如@Martin解释的那样,Google In-App Billing示例中存在一个导致此问题的错误.
但是,在修复它之后,我仍然在内部调用中收到一些错误(queryInventory在queryInventoryAsync极少数情况下创建的线程内部报告没有设置帮助程序).我在这种情况下通过添加额外的catch来解决这个问题:
try {
inv = queryInventory(querySkuDetails, moreSkus);
}
catch (IabException ex) {
result = ex.getResult();
}
catch(IllegalStateException ex){ //ADDED THIS CATCH
result = new IabResult(BILLING_RESPONSE_RESULT_ERROR, "Helper is not setup.");
}
Run Code Online (Sandbox Code Playgroud)
我也遇到了崩溃mHelper.dispose(),我以类似的方式修复了:
try{
if (mContext != null) mContext.unbindService(mServiceConn);
}
catch(IllegalArgumentException ex){ //ADDED THIS CATCH
//IGNORE IT - somehow, the service was already unregistered
}
Run Code Online (Sandbox Code Playgroud)
当然,您可以静默地将它们记录到ACRA,而不是忽略这些错误,例如:)
谢谢你们的评论.
Mar*_*tin 14
IABHelper中有一个错误.缺少异常处理程序中的返回行,这意味着它会通过并调用成功hanlder - 但是,mSetupDone尚未设置,因此对API的进一步调用将失败.如下所示添加return语句 - 这仍然会失败,但失败将正确报告给您的应用程序,以便您采取适当的措施.
catch (RemoteException e) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION,
"RemoteException while setting up in-app billing."));
}
e.printStackTrace();
return; // This return line is missing
}
if (listener != null) {
listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*d M 10
我相信Android代码中仍有两个错误,这就解释了为什么你仍然会看到错误.请注意,调用堆栈位于独立线程上.但是将mSetupDone(IabHelper)设置为true的代码在主UI线程上执行.Java不保证一个线程更改的数据由于CPU缓存而对另一个线程可见,除非您使用volatile关键字声明该变量.因此,它可能是设置(mSetupDone == true),但是mSetupDone的新值缓存在UI线程上,在调用堆栈中此线程尚不可见.所以该线程仍然看到mSetupDone == false.
我尝试通过使用volatile声明mSetupDone以及IabHelper的每个其他非final字段来解决这个问题.
现在另一个问题是.dispose()函数.它不会阻止正在进行的线程.这意味着它可以在其中一个工作线程运行时将mSetupDone设置为false.如果查看queryInventoryAsync(),您将看到它确实检查mSetupDone是否为true.并且基于你的调用堆栈,它确实超越了它.然后它随后以mSetupDone == false崩溃.唯一可能发生的方法是在你的线程处于飞行状态时调用dispose().解决的问题是dispose()需要发出线程信号,以便在看到mSetupDone == false时无声地挽救而不是继续并抛出错误.这也防止了IabHelper的另一个问题,即处置后的实例甚至在被处置后调用了侦听器回调!这里逐行解释有点复杂,但希望这会让你指向正确的方向.
小智 6
我发现!这是关于用户的Google Play商店应用的版本.应用内结算V3需要3.9.16或更高版本(http://developer.android.com/google/play/billing/versions.html).我使用的是旧版本,我收到了这个错误,现在4.4.21就可以了!
| 归档时间: |
|
| 查看次数: |
18244 次 |
| 最近记录: |