IInAppBillingService始终为空,安卓内购查询空指针问题求助
解决应用内购买查询商品时的空指针异常问题
看起来你遇到的空指针异常,大概率是因为IInAppBillingService还没成功绑定就被调用了——毕竟内购服务的绑定是异步的,直接在Activity初始化阶段去调用查询,肯定会踩空。另外你用Handler排查等待问题没效果,可能是没搞对时机,反而打乱了服务绑定的流程。
我给你整理了一套靠谱的修正方案,一步步来:
1. 先确保服务绑定的正确流程
内购服务的绑定必须异步等待回调,不能急着调用方法。你需要在onCreate里发起绑定,然后在onServiceConnected回调里拿到服务实例后,再执行商品查询。
修正后的ServiceConnection和绑定逻辑:
public class AdOnsActivity extends AppCompatActivity { private IInAppBillingService mService; private ServiceConnection mServiceConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 服务绑定成功,初始化mService mService = IInAppBillingService.Stub.asInterface(service); // 这里才是查询商品的正确时机! queryAvailableProducts(); } @Override public void onServiceDisconnected(ComponentName name) { mService = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ad_ons); // 发起内购服务绑定 Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); serviceIntent.setPackage("com.android.vending"); bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE); } // 记得在销毁时解绑服务,避免内存泄漏 @Override protected void onDestroy() { super.onDestroy(); if (mService != null) { unbindService(mServiceConn); } } }
2. 正确实现商品查询逻辑
查询商品的方法必须在子线程执行(直接在主线程调用会触发ANR),拿到结果后再切回主线程更新UI。之前用Handler的思路没错,但要放在正确的地方:
private void queryAvailableProducts() { new Thread(new Runnable() { @Override public void run() { try { // 替换成你自己的商品SKU列表 ArrayList<String> skuList = new ArrayList<>(); skuList.add("premium_feature"); skuList.add("remove_ads"); Bundle queryParams = new Bundle(); queryParams.putStringArrayList("ITEM_ID_LIST", skuList); // 调用内购服务查询商品详情 Bundle skuDetails = mService.getSkuDetails(3, getPackageName(), "inapp", queryParams); int responseCode = skuDetails.getInt("RESPONSE_CODE"); if (responseCode == 0) { ArrayList<String> detailList = skuDetails.getStringArrayList("DETAILS_LIST"); // 切回主线程更新UI runOnUiThread(new Runnable() { @Override public void run() { // 解析商品详情,比如价格、名称等 for (String detail : detailList) { JSONObject skuObj = new JSONObject(detail); String sku = skuObj.getString("productId"); String price = skuObj.getString("price"); // 这里可以把商品信息展示到UI上 } } }); } else { // 处理查询失败的情况,比如提示用户检查网络 runOnUiThread(() -> Toast.makeText(AdOnsActivity.this, "查询商品失败", Toast.LENGTH_SHORT).show()); } } catch (RemoteException | JSONException e) { e.printStackTrace(); runOnUiThread(() -> Toast.makeText(AdOnsActivity.this, "查询出错", Toast.LENGTH_SHORT).show()); } } }).start(); }
3. 别忘了检查基础配置
- 确保
AndroidManifest.xml里添加了内购权限:
<uses-permission android:name="com.android.vending.BILLING" />
- 确认Google Play控制台里的应用内商品已经激活,且SKU和代码里的完全一致,包名也和你的应用匹配。
- 测试时要用签名后的APK,或者用Android Studio的App Signing功能,否则可能无法连接到内购服务。
之前你用Handler排查等待问题没效果,应该是提前在绑定完成前就调用了mService的方法,导致空指针。现在按照这个流程,等服务绑定成功后再查询,就能避免空指针的问题啦。
内容的提问来源于stack exchange,提问作者rootmeanclaire
相关产品推荐
相关产品推荐

