Java Android应用内购买NullPointerException
我犯了一个错误,我快发疯了,因为这只发生在某些情况下,但我真的不明白什么时候,也许一个更专业的眼睛可以帮助我: 从谷歌教程中,我获取了进行应用内购买的代码,简单地说,这段代码是:Java Android应用内购买NullPointerException,java,android,nullpointerexception,in-app-purchase,Java,Android,Nullpointerexception,In App Purchase,我犯了一个错误,我快发疯了,因为这只发生在某些情况下,但我真的不明白什么时候,也许一个更专业的眼睛可以帮助我: 从谷歌教程中,我获取了进行应用内购买的代码,简单地说,这段代码是: 初始化应用程序内服务 检索对象的价格 如果用户单击“购买”按钮,则启动in-purchase 现在,在所有的测试中,我都做得很好(更多的设备和API)但是我收到了大量的报告说:在mHelper上抛出了NullPointerException 我认为当服务被释放时,这种情况会发生在OnDestroy()上,但我不确定,也
初始化应用程序内服务
检索对象的价格
如果用户单击“购买”按钮,则启动in-purchase
mHelper
上抛出了NullPointerException
我认为当服务被释放时,这种情况会发生在OnDestroy()上,但我不确定,也无法修复它(最后完成错误日志)
这是我尽可能多的清理和注释代码:
IabHelper mHelper;
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener;
Activity c;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_room);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
c=this;
//Initialize the In-App Service
mHelper = new IabHelper(this, "my_key");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
//Problem setting up In-app Billing
return;
}
if (mHelper == null) return;
//Ask for the price
List additionalSkuList = new ArrayList();
additionalSkuList.add("SKU_ID");
try {
mHelper.queryInventoryAsync(true, additionalSkuList, mQueryFinishedListener);
}catch (Exception e){
//Fail while asking the price
}
}
});
//Buy Button Listener
b_buy.setOnClickListener(new View.OnClickListener()
{
public void onClick(View V)
{
try {
String payload= "my_payload"
mHelper.launchPurchaseFlow(c, "SKU_ID",1111,mPurchaseFinishedListener, payload);
} catch (Exception e) {
//Error launching purchase flow. Another async operation in progress
}
}
});
// Callback for when a purchase is finished
mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
// if we were disposed of in the meantime, quit.
if (mHelper == null) return;
if (result.isFailure()) {
//Error while buying
return;
}
if (purchase.getSku().equals("SKU_ID")) {
// bought the premium upgrade!
}
}
};
}
//For retrieve the price:
IabHelper.QueryInventoryFinishedListener mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
return;
}
String z = inventory.getSkuDetails("SKU_ID").getPrice();
//The price of the object is + z !!!
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mHelper == null) return;
// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
}
Exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper$2.run (IabHelper.java)
java.lang.Thread.run (Thread.java:818)
这就是错误:
IabHelper mHelper;
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener;
Activity c;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_room);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
c=this;
//Initialize the In-App Service
mHelper = new IabHelper(this, "my_key");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
//Problem setting up In-app Billing
return;
}
if (mHelper == null) return;
//Ask for the price
List additionalSkuList = new ArrayList();
additionalSkuList.add("SKU_ID");
try {
mHelper.queryInventoryAsync(true, additionalSkuList, mQueryFinishedListener);
}catch (Exception e){
//Fail while asking the price
}
}
});
//Buy Button Listener
b_buy.setOnClickListener(new View.OnClickListener()
{
public void onClick(View V)
{
try {
String payload= "my_payload"
mHelper.launchPurchaseFlow(c, "SKU_ID",1111,mPurchaseFinishedListener, payload);
} catch (Exception e) {
//Error launching purchase flow. Another async operation in progress
}
}
});
// Callback for when a purchase is finished
mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
// if we were disposed of in the meantime, quit.
if (mHelper == null) return;
if (result.isFailure()) {
//Error while buying
return;
}
if (purchase.getSku().equals("SKU_ID")) {
// bought the premium upgrade!
}
}
};
}
//For retrieve the price:
IabHelper.QueryInventoryFinishedListener mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
return;
}
String z = inventory.getSkuDetails("SKU_ID").getPrice();
//The price of the object is + z !!!
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mHelper == null) return;
// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
}
Exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper$2.run (IabHelper.java)
java.lang.Thread.run (Thread.java:818)
下面是Google IabHelper类的一些涉及的方法(可能您不需要阅读此内容)它们刚刚在错误日志中提到,由Google编写: 处置:
public void dispose() {
logDebug("Disposing.");
mSetupDone = false;
if (mServiceConn != null) {
logDebug("Unbinding from service.");
if (mContext != null) mContext.unbindService(mServiceConn);
}
mDisposed = true;
mContext = null;
mServiceConn = null;
mService = null;
mPurchaseListener = null;
}
开始安装:
public void startSetup(final OnIabSetupFinishedListener listener) {
// If already set up, can't do it again.
checkNotDisposed();
if (mSetupDone) throw new IllegalStateException("IAB helper is already set up.");
// Connection to IAB service
logDebug("Starting in-app billing setup.");
mServiceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
logDebug("Billing service disconnected.");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (mDisposed) return;
logDebug("Billing service connected.");
mService = IInAppBillingService.Stub.asInterface(service);
String packageName = mContext.getPackageName();
try {
logDebug("Checking for in-app billing 3 support.");
// check for in-app billing v3 support
int response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
if (response != BILLING_RESPONSE_RESULT_OK) {
if (listener != null) listener.onIabSetupFinished(new IabResult(response,
"Error checking for billing v3 support."));
// if in-app purchases aren't supported, neither are subscriptions.
mSubscriptionsSupported = false;
return;
}
logDebug("In-app billing version 3 supported for " + packageName);
// check for v3 subscriptions support
response = mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscriptions AVAILABLE.");
mSubscriptionsSupported = true;
}
else {
logDebug("Subscriptions NOT AVAILABLE. Response: " + response);
}
mSetupDone = true;
}
catch (RemoteException e) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION,
"RemoteException while setting up in-app billing."));
}
e.printStackTrace();
return;
}
if (listener != null) {
listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
}
}
};
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
}
else {
// no service available to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Billing service unavailable on device."));
}
}
}
和IAB助手的构造函数:
public IabHelper(Context ctx, String base64PublicKey) {
mContext = ctx.getApplicationContext();
mSignatureBase64 = base64PublicKey;
logDebug("IAB helper created.");
}
是完整的IbaHelper类
重述:
IabHelper mHelper;
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener;
Activity c;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_room);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
c=this;
//Initialize the In-App Service
mHelper = new IabHelper(this, "my_key");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
//Problem setting up In-app Billing
return;
}
if (mHelper == null) return;
//Ask for the price
List additionalSkuList = new ArrayList();
additionalSkuList.add("SKU_ID");
try {
mHelper.queryInventoryAsync(true, additionalSkuList, mQueryFinishedListener);
}catch (Exception e){
//Fail while asking the price
}
}
});
//Buy Button Listener
b_buy.setOnClickListener(new View.OnClickListener()
{
public void onClick(View V)
{
try {
String payload= "my_payload"
mHelper.launchPurchaseFlow(c, "SKU_ID",1111,mPurchaseFinishedListener, payload);
} catch (Exception e) {
//Error launching purchase flow. Another async operation in progress
}
}
});
// Callback for when a purchase is finished
mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
// if we were disposed of in the meantime, quit.
if (mHelper == null) return;
if (result.isFailure()) {
//Error while buying
return;
}
if (purchase.getSku().equals("SKU_ID")) {
// bought the premium upgrade!
}
}
};
}
//For retrieve the price:
IabHelper.QueryInventoryFinishedListener mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
return;
}
String z = inventory.getSkuDetails("SKU_ID").getPrice();
//The price of the object is + z !!!
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mHelper == null) return;
// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
}
Exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper.startSetup (IabHelper.java)
__null__.dispose (IabHelper.java)
__null__.launchPurchaseFlow (IabHelper.java)
__null__.handleActivityResult (IabHelper.java)
__null__.queryInventory (IabHelper.java)
__null__.queryInventoryAsync (IabHelper.java)
__null__.getResponseDesc (IabHelper.java)
__null__.checkSetupDone (IabHelper.java)
__null__.getResponseCodeFromBundle (IabHelper.java)
__null__.getResponseCodeFromIntent (IabHelper.java)
__null__.queryPurchases (IabHelper.java)
__null__.querySkuDetails (IabHelper.java)
com.myproj.util.IabHelper$2.run (IabHelper.java)
java.lang.Thread.run (Thread.java:818)
告诉我是否可以看到变量mHelper
的NullPointerException
被抛出的位置/时间。由于工作正常,我无法从代码中查看并使用虚拟和物理设备进行测试
我非常确定在活动关闭后会抛出错误,但我不明白为什么要修复它
如果需要更多信息,请写信。谢谢大家 您应该尽量避免使用getApplicationContext(),因为这会大大增加强制关闭的机会。 使用活动上下文。如果您在活动中创建IabHelper的对象,则传递ActivityName。这表示活动上下文 如果您在片段中,请使用getActivity() 在类中,使用如下内容:
public IabHelper(Context ctx, String base64PublicKey) {
mContext = ctx;
mSignatureBase64 = base64PublicKey;
logDebug("IAB helper created.");
}
我希望它能正常工作 您将
新的IabHelper.OnIabSetupFinishedListener(){…}
传递到startSetup()中,但mHelper.startSetup()不保留引用,onCreate()也不保留引用。看起来您有一个属性(mppurchaseListener
)来保存侦听器,但没有使用它-而是创建一个匿名类并将其传递给startSetup()。。。然后您的实例将被垃圾收集,因为没有引用。您可以用完整的堆栈跟踪更新您的问题吗Null,我无法引发错误,但可以肯定,它发生在活动结束后closed@GMX,在代码中,mHelper
usage会抛出一个NPE吗?我会尽快测试这个