Android应用内计费获取商品价格时崩溃问题求助
搞定Android In-app Billing获取商品价格时的崩溃问题
嘿,看来你在搭建Android内购功能时卡在了获取商品价格的环节,崩溃确实挺头疼的!先回顾下你已经完成的准备工作:
- 添好了AIDL文件和util-helper工具类
- 在Play Console创建了应用、上传了签名APK,也配置好了内购商品
- Shop.java的onCreate里已经写了部分初始化代码
针对你标记的**//THIS IS WHERE THE APP CRASHES**位置的崩溃,我整理了几个最常见的排查方向和解决方案:
1. 先确认内购服务是否完成初始化
崩溃最常见的原因是:你还没等IabHelper成功连接到Google Play服务,就直接调用了获取商品价格的方法。内购的初始化是异步的,必须在onIabSetupFinished回调里再执行商品查询逻辑,不能直接在onCreate里同步调用。
给你一个标准的代码结构参考:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化内购助手 String billingKey = "XXX"; // 你的内购密钥 mHelper = new IabHelper(this, billingKey); // 启动异步初始化 mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { if (!result.isSuccess()) { // 初始化失败,先处理错误(比如提示用户) Log.d("Shop", "内购初始化失败: " + result.getMessage()); return; } // 初始化成功!这里再调用获取商品价格的方法 fetchProductPrice(); } }); } private void fetchProductPrice() { // 要查询的商品ID列表 ArrayList<String> skuList = new ArrayList<>(); skuList.add("your_product_id"); // 替换成你在Play Console创建的商品ID // 异步查询商品详情 mHelper.queryInventoryAsync(true, skuList, null, new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResult result, Inventory inventory) { if (result.isFailure()) { Log.e("Shop", "查询商品失败: " + result.getMessage()); return; } // 安全地获取商品价格 if (inventory != null) { SkuDetails skuDetails = inventory.getSkuDetails("your_product_id"); if (skuDetails != null) { String productPrice = skuDetails.getPrice(); // 这里处理价格显示逻辑 } else { Log.e("Shop", "找不到对应商品,请检查商品ID是否和Play Console一致"); } } } }); }
2. 检查商品ID和Play Console配置的一致性
- 代码里用的商品ID必须和Play Console中创建的内购商品ID完全一致(大小写敏感,多一个空格都不行)
- 确认你上传到Play Console的APK是正式签名包,而且你测试用的APK和这个包的签名完全相同(内购对签名验证很严格)
- 如果用测试账号测试,要确保这个账号已经被添加到Play Console的内部测试列表里,并且已经接受了测试邀请
3. 空指针异常的防御性检查
如果崩溃是空指针异常,大概率是inventory或者skuDetails为null导致的。一定要在调用getPrice()之前做非空判断,就像上面示例代码里那样,不要直接调用方法。
4. 权限和基础配置检查
- 确保AndroidManifest.xml里添加了内购必需的权限:
<uses-permission android:name="com.android.vending.BILLING" />
- 如果你用的是旧版AIDL方式,确认AIDL文件的路径和包名完全正确;如果是新版Billing Library,要确保build.gradle里的依赖引入正确
最后提个小建议:崩溃时一定要看Logcat的错误栈信息,它能直接告诉你是哪一行代码出了问题(比如是空指针、服务未连接还是权限被拒),这会让排查效率高很多!
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

