Billing API v3 Iabhelper NullPointerException
изменить 4/15: улавливание nullpointer в IabHelper, похоже, остановило эту проблему. Я больше не вижу исключений, которые бросаются, я собираюсь принять это как ответ.
edit 4/04: немного более глубокое погружение. Существуют блоки try catch, которые обрабатывают RemoteExceptions и JSONExceptions для метода queryPurchases, но не обрабатывают NullPointerException. То, что я собираюсь попробовать, это включить исключение NullPointer обработка так IabHelper выглядит так при попытке querySkuDetails:
catch (NullPointerException e) {
throw new IabException(IABHELPER_UNKNOWN_ERROR, "NullPointer while refreshing inventory.", e);
}
Я только что подал ошибку на это:
https://code.google.com/p/marketbilling/issues/detail?id=114
изменить 3/25: ну, все еще получаю этот сбой... теперь это происходит при попытке получить контекст в строке 3 следующего отрывка из IabHelper:
int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException {
logDebug("Querying owned items, item type: " + itemType);
logDebug("Package name: " + mContext.getPackageName());
это неприятно, потому что в моем манифесте я всегда используйте полный путь к моему приложению для "имя".
пример " com.myappname.чепуха.Имя_класса"
я также пытался передать это, MyClass.это, getApplicationContext () к mHelper. Однако все они производят одни и те же результаты NullPointer случайным образом из устройств в дикой природе. Я также попробовал name=".MyClass " в манифесте. Вот как это выглядит в настоящее время:
mHelper = new IabHelper(MyClass.this, myKey);
edit 3/18/13: я все еще получаю исключения, даже с новая версия IabHelper развернута на 3/17.
я начинаю видеть шаблон здесь, что сбои все при попытке получить контекст при выполнении mContext.getPackageName(). Мне любопытно, почему это работает на всех моих тестовых устройствах, и я не могу воспроизвести этот сбой, и только кажется, что на небольшом количестве устройств.
вот новый сбой:
java.lang.NullPointerException
at com.myapp.util.IabHelper.queryPurchases(SourceFile:836)
at com.myapp.util.IabHelper.queryInventory(SourceFile:558)
at com.myapp.util.IabHelper.queryInventory(SourceFile:522)
at com.myapp.util.IabHelper.run(SourceFile:617)
at java.lang.Thread.run(Thread.java:1019)
вызвано IabHelper...
line 836: logDebug("Package name: " + mContext.getPackageName());
edit 3/17/13: Я вижу, что за последние несколько месяцев было опубликовано много исправлений ошибок, я попробую последний код, доступный здесь, и посмотрю, решит ли это проблему:
в одном из моих приложений я использую API биллинга и стандартный код, включенный в него.
я использую последнюю версию биллинг API доступны через менеджер SDK по состоянию на 16.03.2013.
в своей деятельности я запрашиваю инвентарь, используя следующее:
final List<String> skuList = new ArrayList<String>();
skuList.add("sku1");
skuList.add("sku2");
skuList.add("sku3");
if (skuList != null) {
if (skuList.size() > 0) {
try {
mHelper.queryInventoryAsync(true, skuList, mGotInventoryListener);
} catch (Exception e) {
ACRA.getErrorReporter().handleException(e);
}
}
}
я получаю несколько отчетов NullPointerException в диком виде из класса IabHelper для следующих устройств. Я не могу воспроизвести проблему и не могу найти никакой информации об этих сбоях, и это причина, по которой я публикую этот вопрос.
у меня есть бесчисленное множество других проверок для нулей и блоков try / catch в " developer облицовка " часть API биллинга, в том числе в onQueryInventoryFinished, поэтому я знаю, что это исключение не выбрасывается из "моего кода" (потому что я не фиксирую сбои из любого из классов моего приложения), а вместо этого выбрасывается из самого IabHelper. Я не изменил IabHelper, кроме этого рекомендуемого исправления:https://stackoverflow.com/a/14737699
Авария # 1 Galaxy Nexus
java.lang.NullPointerException
at com.myapp.util.IabHelper.querySkuDetails(SourceFile:802)
at com.myapp.util.IabHelper.queryInventory(SourceFile:471)
at com.myapp.util.IabHelper.run(SourceFile:521)
at java.lang.Thread.run(Thread.java:856)
вызвана Иабхелпер...
line 802: Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(), ITEM_TYPE_INAPP, querySkus);
авария #2 Samsung GT-S5570L
java.lang.NullPointerException
at com.myapp.util.IabHelper.queryPurchases(SourceFile:735)
at com.myapp.util.IabHelper.queryInventory(SourceFile:465)
at com.myapp.util.IabHelper.run(SourceFile:521)
at java.lang.Thread.run(Thread.java:1019)
вызвано IabHelper...
line 735: Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(), ITEM_TYPE_INAPP, continueToken);
6 ответов:
изменить 4/15: улавливание nullpointer в IabHelper, похоже, остановило эту проблему. Я больше не вижу исключений, которые бросаются, я собираюсь принять это как ответ.
изменить 4/04: немного более глубокое погружение. Существуют блоки try catch, которые обрабатывают RemoteExceptions и JSONExceptions для метода queryPurchases, но не обрабатывают NullPointerException. То, что я собираюсь попробовать, это включить обработку исключений NullPointer, поэтому IabHelper выглядит так при попытке querySkuDetails:
catch (NullPointerException e) { throw new IabException(IABHELPER_UNKNOWN_ERROR, "NullPointer while refreshing inventory.", e); }Я только что подал ошибку на это:
https://code.google.com/p/marketbilling/issues/detail?id=114
изменить
if (querySkuDetails) { r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus); if (r != BILLING_RESPONSE_RESULT_OK) { throw new IabException(r, "Error refreshing inventory (querying prices of items)."); } }до
if (querySkuDetails) { try { r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus); if (r != BILLING_RESPONSE_RESULT_OK) { throw new IabException(r, "Error refreshing inventory (querying prices of items)."); } } catch (NullPointerException e) { throw new IabException(IABHELPER_UNKNOWN_ERROR, "NPE while refreshing inventory.", e); } }изменить
if (querySkuDetails) { r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreSubsSkus); if (r != BILLING_RESPONSE_RESULT_OK) { throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions)."); } }до
if (querySkuDetails) { try { r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreSubsSkus); if (r != BILLING_RESPONSE_RESULT_OK) { throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions)."); } } catch (NullPointerException e) { throw new IabException(IABHELPER_UNKNOWN_ERROR, "NPE while refreshing inventory.", e); } }
вы вероятно используете асинхронные операции. Текущий IabHelper не является безопасным в случае, если вы используете ...асинхронные методы. Проблема в том, что в любой момент асинхронная операция выполняется dispose может быть вызвана в главном потоке. В этом случае вы получите возникновению исключительных ситуаций типа NullPointerException и IllegalStateExceptions.
вот патч, исправляющий это:
Index: src/com/evotegra/aCoDriver/iabUtil/IabHelper.java =================================================================== --- src/com/evotegra/aCoDriver/iabUtil/IabHelper.java (revision 1162) +++ src/com/evotegra/aCoDriver/iabUtil/IabHelper.java (working copy) @@ -86,7 +86,10 @@ // Is an asynchronous operation in progress? // (only one at a time can be in progress) - boolean mAsyncInProgress = false; + volatile boolean mAsyncInProgress = false; + + // is set to true if dispose is called while a thread is running. Allows graceful shutdown + volatile boolean mDisposeRequested = false; // (for logging/debugging) // if mAsyncInProgress == true, what asynchronous operation is in progress? @@ -285,6 +288,12 @@ * disposed of, it can't be used again. */ public void dispose() { + // do not dispose while an async Thread is running. Will cause all kinds of exceptions. + // In this case dispose must be called from thread after setting mAsyncInProgress to true + if (mAsyncInProgress) { + mDisposeRequested = true; + return; + } logDebug("Disposing."); mSetupDone = false; if (mServiceConn != null) { @@ -827,6 +836,7 @@ logDebug("Ending async operation: " + mAsyncOperation); mAsyncOperation = ""; mAsyncInProgress = false; + if (mDisposeRequested) IabHelper.this.dispose(); }или скачать патч здесь. http://code.google.com/p/marketbilling/issues/detail?id=139&thanks=139&ts=1375614409
слегка изменить начало
queryPurchasesметод выглядит так:int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException { // Query purchases //logDebug("Querying owned items, item type: " + itemType); //logDebug("Package name: " + mContext.getPackageName()); boolean verificationFailed = false; String continueToken = null; do { // logDebug("Calling getPurchases with continuation token: " + continueToken); if(mDisposed || mService==null) return IABHELPER_UNKNOWN_ERROR; Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(), itemType, continueToken);спасибо sebastie за указание на причину этого.
Если вы получаете эту ошибку на эмуляторе, это может быть очень простая вещь, которая случается более чем в половине случаев.
проверьте, что вы используете Google API SDK, а не обычный SDK!!!
iabhelper устарел и был заменен BillingClient. См.https://developer.android.com/google/play/billing/billing_library.html
Comments