Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android应用内购买NullPointerException_Java_Android_Nullpointerexception_In App Purchase - Fatal编程技术网

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
  • 现在,在所有的测试中,我都做得很好(更多的设备和API)但是我收到了大量的报告说:在
    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吗?我会尽快测试这个