I am using the In-app Billing service of Google and Proguard. The configuration file that I am using as a Proguard is the one in .../sdk/tools/proguard/proguard-android.txt
As Google says here: http://developer.android.com/google/play/billing/billing_best_practices.html I added the following line in the configuration file:
-keep class com.android.vending.billing.**
I am using the updated files of IAB from Google as well: https://code.google.com/p/marketbilling/source/detail?r=7ec85a9b619fc5f85023bc8125e7e6b1ab4dd69f
The problem is that sometimes, users report random crashes with this stacktrace:
E/AndroidRuntime: FATAL EXCEPTION: Thread-455
java.lang.NullPointerException
at com.xx.xxxx.util.IabHelper.startSetup(Unknown Source)
at com.xx.xxxx.util.IabHelper$2.run(Unknown Source)
at java.lang.Thread.run(Thread.java:856)
It also happened in my device (just opening the app) but only happened once to me today.
And I am not sure if it is problems of Google files (of IAB) or something is missing in the Proguard configuration file.
Adding the following string
-keep class com.android.vending.billing.**
to ProGuard configuration tells him to not to obfuscate that package.
Exception comes from com.xx.xxxx.util.IabHelper, so you can try to add something like
-keep class com.xx.xxxx.util.IabHelper.**
to keep your package as it was without ProGuard.
Your proguard configuration is correct. I even allow to obfuscate generated com.android.vending.billing.IInAppBillingService
in my app and everything works just fine.
Regarding IabHelper
class. I would not suggest to use it "as is". Firstly, it is proven to be buggy. Secondly, it can be hacked by automatic tools even when obfuscated. I suggest to write your own class based on IabHelper
and write junit tests for it. This is what I did for my project too.
This line in IabHelpers startSetup()
mContext.getPackageManager()
.queryIntentServices(serviceIntent, 0);
Can sometimes return null, so when checking if the list is empty you get the nullpointer.
I simply modified it to check for null before doing anything else;
List<ResolveInfo> queryIntentServices = mContext.getPackageManager()
.queryIntentServices(serviceIntent, 0);
if (queryIntentServices != null && !queryIntentServices.isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn,
Context.BIND_AUTO_CREATE);
}else ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With