Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/192.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
Android 谷歌应用内计费,祝酒会打破一切_Android_In App Billing_Play Billing Library - Fatal编程技术网

Android 谷歌应用内计费,祝酒会打破一切

Android 谷歌应用内计费,祝酒会打破一切,android,in-app-billing,play-billing-library,Android,In App Billing,Play Billing Library,我甚至不知道这个问题应该有什么标题 因此,我正在开发一个库,以使谷歌账单尽可能易于集成 在我将库升级到Google的计费v4之后,一切都开始了,它将Purchase#getSku替换为Purchase#getSkus() 这是迁移到计费v4之前和之后的步骤: 之前(v3库): private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) { if

我甚至不知道这个问题应该有什么标题

因此,我正在开发一个库,以使
谷歌账单
尽可能易于集成

在我将库升级到
Google的计费v4
之后,一切都开始了,它将
Purchase#getSku
替换为
Purchase#getSkus()

这是迁移到
计费v4
之前和之后的步骤:

之前(v3库):

private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchase.getSku())).findFirst();
                if (skuInfo.isPresent()) {
                    SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                    PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                    signatureValidPurchases.add(purchaseInfo);

                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                //query all SKUs as a list
                List<String> purchasesSkus = purchase.getSkus();

                //loop through all SKUs and progress for each SKU individually
                for (int i = 0; i < purchasesSkus.size(); i++) {
                    String purchasesSku = purchasesSkus.get(i);

                    Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchasesSku)).findFirst();
                    if (skuInfo.isPresent()) {
                        SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                        PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                        signatureValidPurchases.add(purchaseInfo);

                    }
                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
解释问题:

private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchase.getSku())).findFirst();
                if (skuInfo.isPresent()) {
                    SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                    PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                    signatureValidPurchases.add(purchaseInfo);

                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                //query all SKUs as a list
                List<String> purchasesSkus = purchase.getSkus();

                //loop through all SKUs and progress for each SKU individually
                for (int i = 0; i < purchasesSkus.size(); i++) {
                    String purchasesSku = purchasesSkus.get(i);

                    Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchasesSku)).findFirst();
                    if (skuInfo.isPresent()) {
                        SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                        PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                        signatureValidPurchases.add(purchaseInfo);

                    }
                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
当使用上述
Before(v3-library)
中的代码时,一切都按预期工作,监听器将被触发并显示toast。在切换到(v4库)toast之后,会破坏一切。日志已在
logcat
中注册,但toast不会显示。更重要的是,如果我在toast之后调用另一个日志,它也不会被注册,事实上,在toast之后不会调用任何东西,甚至
finish()
。但是,等等,还有更多的,如果我一点也不祝酒的话,一切都很顺利。如果我将
toast
替换为
snackbar
,snackbar将显示

什么会导致这个问题?有什么想法吗

更新:

private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchase.getSku())).findFirst();
                if (skuInfo.isPresent()) {
                    SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                    PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                    signatureValidPurchases.add(purchaseInfo);

                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                //query all SKUs as a list
                List<String> purchasesSkus = purchase.getSkus();

                //loop through all SKUs and progress for each SKU individually
                for (int i = 0; i < purchasesSkus.size(); i++) {
                    String purchasesSku = purchasesSkus.get(i);

                    Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchasesSku)).findFirst();
                    if (skuInfo.isPresent()) {
                        SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                        PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                        signatureValidPurchases.add(purchaseInfo);

                    }
                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
如果我延迟调用
Toast
,一切都会正常工作

final Handler handler = new Handler(Looper.getMainLooper());
                        String finalSku = sku;
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(SettingsActivity.this, "Fetched: " + finalSku, Toast.LENGTH_SHORT).show();
                            }
                        }, 100);
更新2:

private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchase.getSku())).findFirst();
                if (skuInfo.isPresent()) {
                    SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                    PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                    signatureValidPurchases.add(purchaseInfo);

                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
private void processPurchases(List<Purchase> allPurchases, boolean purchasedProductsFetched) {
        if (!allPurchases.isEmpty()) {

            List<PurchaseInfo> signatureValidPurchases = new ArrayList<>();

            //create a list with signature valid purchases
            List<Purchase> validPurchases = allPurchases.stream().filter(this::isPurchaseSignatureValid).collect(Collectors.toList());
            for (Purchase purchase : validPurchases) {

                //query all SKUs as a list
                List<String> purchasesSkus = purchase.getSkus();

                //loop through all SKUs and progress for each SKU individually
                for (int i = 0; i < purchasesSkus.size(); i++) {
                    String purchasesSku = purchasesSkus.get(i);

                    Optional<SkuInfo> skuInfo = fetchedSkuInfoList.stream().filter(it -> it.getSkuId().equals(purchasesSku)).findFirst();
                    if (skuInfo.isPresent()) {
                        SkuDetails skuDetails = skuInfo.get().getSkuDetails();

                        PurchaseInfo purchaseInfo = new PurchaseInfo(generateSkuInfo(skuDetails), purchase);
                        signatureValidPurchases.add(purchaseInfo);

                    }
                }
            }

            if (purchasedProductsFetched) {
                fetchedPurchasedProducts = true;
                billingEventListener.onPurchasedProductsFetched(signatureValidPurchases);
            } else {
                billingEventListener.onProductsPurchased(signatureValidPurchases);
            }

            purchasedProductsList.addAll(signatureValidPurchases);

            for (PurchaseInfo purchaseInfo : signatureValidPurchases) {
                consume(purchaseInfo);

                if (shouldAutoAcknowledge) {
                    boolean wasConsumedBefore = purchaseInfo.getSkuProductType() == SkuProductType.CONSUMABLE;
                    if (!wasConsumedBefore) {
                        acknowledgePurchase(purchaseInfo);
                    }
                }
            }
        }
    }
Logcat。注意
D/IapConnector:SKU FOUND:test_purchase7
被调用,它是
Toast
之前的
日志

2021-06-07 11:11:37.633 31680-31680/games.moisoni.evfp I/ViewRootImpl@ef10be4[MainActivity]: ViewPostIme pointer 0
2021-06-07 11:11:37.710 31680-31680/games.moisoni.evfp I/ViewRootImpl@ef10be4[MainActivity]: ViewPostIme pointer 1
2021-06-07 11:11:37.747 31680-32423/games.moisoni.evfp V/FA: Recording user engagement, ms: 11555
2021-06-07 11:11:37.752 31680-32423/games.moisoni.evfp V/FA: Connecting to remote service
2021-06-07 11:11:37.755 31680-32423/games.moisoni.evfp V/FA: Activity paused, time: 53257103
2021-06-07 11:11:37.769 31680-32423/games.moisoni.evfp V/FA: Connection attempt already in progress
2021-06-07 11:11:37.770 31680-32417/games.moisoni.evfp V/FA: onActivityCreated
2021-06-07 11:11:37.772 31680-31680/games.moisoni.evfp I/DecorView: [INFO] isPopOver=false, config=true
2021-06-07 11:11:37.772 31680-31680/games.moisoni.evfp I/DecorView: updateCaptionType >> DecorView@25a7196[], isFloating=false, isApplication=true, hasWindowDecorCaption=false, hasWindowControllerCallback=true
2021-06-07 11:11:37.772 31680-31680/games.moisoni.evfp D/DecorView: setCaptionType = 0, this = DecorView@25a7196[]
2021-06-07 11:11:37.782 31680-31680/games.moisoni.evfp D/ScrollView: initGoToTop
2021-06-07 11:11:37.830 31680-31680/games.moisoni.evfp D/IapConnector: Billing service: connecting...
2021-06-07 11:11:37.853 31680-32423/games.moisoni.evfp V/FA: Activity resumed, time: 53257213
2021-06-07 11:11:37.857 31680-31680/games.moisoni.evfp D/InputTransport: Input channel constructed: 'f0be3be', fd=218
2021-06-07 11:11:37.859 31680-31680/games.moisoni.evfp I/ViewRootImpl@d0eac04[SettingsActivity]: setView = com.android.internal.policy.DecorView@25a7196 TM=true
2021-06-07 11:11:37.870 31680-32423/games.moisoni.evfp V/FA: Connection attempt already in progress
2021-06-07 11:11:37.872 31680-32423/games.moisoni.evfp V/FA: Connection attempt already in progress
2021-06-07 11:11:37.879 31680-31680/games.moisoni.evfp D/ViewRootImpl@d0eac04[SettingsActivity]: controlInsetsForCompatibility: hideByFlags=0x3, showByFlags=0x0, flags=0x89810500, sysUiVis=0x1706, matchParent=true, nonAttachedAppWindow=true
2021-06-07 11:11:37.879 31680-31680/games.moisoni.evfp D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=1, host=games.moisoni.evfp/games.moisoni.evfp.SettingsActivity, from=android.view.InsetsSourceConsumer.hide:236 android.view.InsetsController.collectSourceControls:1172 android.view.InsetsController.controlAnimationUnchecked:1049 android.view.InsetsController.applyAnimation:1417 android.view.InsetsController.hide:984 android.view.InsetsController.hide:967 android.view.ViewRootImpl.controlInsetsForCompatibility:2852 android.view.ViewRootImpl.performTraversals:3314 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9965 
2021-06-07 11:11:37.879 31680-31680/games.moisoni.evfp D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=0, host=games.moisoni.evfp/games.moisoni.evfp.SettingsActivity, from=android.view.InsetsSourceConsumer.hide:236 android.view.InsetsController.collectSourceControls:1172 android.view.InsetsController.controlAnimationUnchecked:1049 android.view.InsetsController.applyAnimation:1417 android.view.InsetsController.hide:984 android.view.InsetsController.hide:967 android.view.ViewRootImpl.controlInsetsForCompatibility:2852 android.view.ViewRootImpl.performTraversals:3314 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9965 
2021-06-07 11:11:37.893 31680-31680/games.moisoni.evfp I/SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0xa900b0f / android.view.SurfaceControl.readFromParcel:1115 android.view.IWindowSession$Stub$Proxy.relayout:1820 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9965 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995 
2021-06-07 11:11:37.894 31680-31680/games.moisoni.evfp I/ViewRootImpl@d0eac04[SettingsActivity]: Relayout returned: old=(0,0,1440,3040) new=(0,144,1440,3040) req=(1440,3040)0 dur=10 res=0x7 s={true 535365349344} ch=true fn=-1
2021-06-07 11:11:37.902 31680-31680/games.moisoni.evfp D/ScrollView:  onsize change changed 
2021-06-07 11:11:37.902 31680-31680/games.moisoni.evfp I/ViewRootImpl@d0eac04[SettingsActivity]: [DP] dp(1) 1 android.view.ViewRootImpl.reportNextDraw:10951 android.view.ViewRootImpl.performTraversals:3845 android.view.ViewRootImpl.doTraversal:2618 
2021-06-07 11:11:37.902 31680-31680/games.moisoni.evfp I/ViewRootImpl@d0eac04[SettingsActivity]: [DP] pd() Asnyc report
2021-06-07 11:11:37.922 31680-31680/games.moisoni.evfp I/ViewRootImpl@d0eac04[SettingsActivity]: [DP] pdf(0) 1 android.view.ViewRootImpl.lambda$performDraw$1$ViewRootImpl:4668 android.view.-$$Lambda$ViewRootImpl$DJd0VUYJgsebcnSohO6h8zc_ONI.run:6 android.os.Handler.handleCallback:938 
2021-06-07 11:11:37.922 31680-31680/games.moisoni.evfp I/ViewRootImpl@d0eac04[SettingsActivity]: [DP] rdf()
2021-06-07 11:11:37.927 31680-31680/games.moisoni.evfp I/ViewRootImpl@ef10be4[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 0 1
2021-06-07 11:11:37.928 31680-32758/games.moisoni.evfp D/IapConnector: Billing service: connected
2021-06-07 11:11:37.933 31680-32423/games.moisoni.evfp D/FA: Connected to remote service
2021-06-07 11:11:37.935 31680-32423/games.moisoni.evfp V/FA: Processing queued up service tasks: 4
2021-06-07 11:11:37.938 31680-32759/games.moisoni.evfp D/IapConnector: Query SKU Details: data found
2021-06-07 11:11:37.938 31680-32758/games.moisoni.evfp D/IapConnector: Subscriptions support check: success
2021-06-07 11:11:37.939 31680-32759/games.moisoni.evfp D/IapConnector: SKU FOUND: test_purchase7
2021-06-07 11:11:37.940 31680-32759/games.moisoni.evfp D/CompatibilityChangeReporter: Compat change id reported: 147798919; UID 10745; state: ENABLED
2021-06-07 11:11:37.948 31680-31680/games.moisoni.evfp D/SurfaceControl: hide : mNativeObject = 531070505712 - sc.mNativeObject = 530532840928 - Surface(name=Surface(name=a8e3812 NavigationBar0)/@0x38b32cd - animation-leash)/@0x2a3e45d
2021-06-07 11:11:37.948 31680-31680/games.moisoni.evfp D/SurfaceControl: nativeSetFlags Done : Surface(name=Surface(name=a8e3812 NavigationBar0)/@0x38b32cd - animation-leash)/@0x2a3e45d
2021-06-07 11:11:37.949 31680-31680/games.moisoni.evfp D/SurfaceControl: hide : mNativeObject = 531070497088 - sc.mNativeObject = 530532838464 - Surface(name=Surface(name=e511e35 StatusBar)/@0xbf071b - animation-leash)/@0xc4ac1d2
2021-06-07 11:11:37.949 31680-31680/games.moisoni.evfp D/SurfaceControl: nativeSetFlags Done : Surface(name=Surface(name=e511e35 StatusBar)/@0xbf071b - animation-leash)/@0xc4ac1d2
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: release : mNativeObject = 530532781344 - Surface(name=Surface(name=37630c6 InputMethod)/@0xd11e623 - animation-leash)/@0xe000b05 / android.view.-$$Lambda$Rl1VZmNJ0VZDLK0BAbaVGis0rrA.accept:2 android.view.InsetsSourceControl.release:170 android.view.InsetsSourceConsumer.setControl:202 android.view.ImeInsetsSourceConsumer.setControl:154 
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject s[530532781344]
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject e[530532781344]
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: release : mNativeObject = 530532786048 - Surface(name=Surface(name=a8e3812 NavigationBar0)/@0x38b32cd - animation-leash)/@0xd4eb2a3 / android.view.-$$Lambda$Rl1VZmNJ0VZDLK0BAbaVGis0rrA.accept:2 android.view.InsetsSourceControl.release:170 android.view.InsetsSourceConsumer.setControl:202 android.view.InsetsController.onControlsChanged:833 
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject s[530532786048]
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject e[530532786048]
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: release : mNativeObject = 530532732064 - Surface(name=Surface(name=e511e35 StatusBar)/@0xbf071b - animation-leash)/@0x201e9a0 / android.view.-$$Lambda$Rl1VZmNJ0VZDLK0BAbaVGis0rrA.accept:2 android.view.InsetsSourceControl.release:170 android.view.InsetsSourceConsumer.setControl:202 android.view.InsetsController.onControlsChanged:833 
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject s[530532732064]
2021-06-07 11:11:37.951 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject e[530532732064]
2021-06-07 11:11:37.955 31680-31680/games.moisoni.evfp I/ViewRootImpl@d0eac04[SettingsActivity]: MSG_WINDOW_FOCUS_CHANGED 1 1
2021-06-07 11:11:37.955 31680-31680/games.moisoni.evfp D/InputMethodManager: prepareNavigationBarInfo() DecorView@25a7196[SettingsActivity]
2021-06-07 11:11:37.955 31680-31680/games.moisoni.evfp D/InputMethodManager: getNavigationBarColor() -16711423
2021-06-07 11:11:37.957 31680-31680/games.moisoni.evfp D/InputMethodManager: prepareNavigationBarInfo() DecorView@25a7196[SettingsActivity]
2021-06-07 11:11:37.957 31680-31680/games.moisoni.evfp D/InputMethodManager: getNavigationBarColor() -16711423
2021-06-07 11:11:37.957 31680-31680/games.moisoni.evfp V/InputMethodManager: Starting input: tba=games.moisoni.evfp ic=null mNaviBarColor -16711423 mIsGetNaviBarColorSuccess true , NavVisible : false , NavTrans : false
2021-06-07 11:11:37.957 31680-31680/games.moisoni.evfp D/InputMethodManager: startInputInner - Id : 0
2021-06-07 11:11:37.957 31680-31680/games.moisoni.evfp I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
2021-06-07 11:11:37.959 31680-31680/games.moisoni.evfp D/InputTransport: Input channel constructed: 'ClientS', fd=221
2021-06-07 11:11:37.959 31680-31680/games.moisoni.evfp D/InputTransport: Input channel destroyed: 'ClientS', fd=111
2021-06-07 11:11:37.998 31680-31680/games.moisoni.evfp I/SurfaceControl: release : mNativeObject = 530532838240 - Surface(name=Surface(name=37630c6 InputMethod)/@0xd11e623 - animation-leash)/@0x46f291e / android.view.-$$Lambda$Rl1VZmNJ0VZDLK0BAbaVGis0rrA.accept:2 android.view.InsetsSourceControl.release:170 android.view.InsetsSourceConsumer.setControl:202 android.view.ImeInsetsSourceConsumer.setControl:154 
2021-06-07 11:11:37.998 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject s[530532838240]
2021-06-07 11:11:37.998 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject e[530532838240]
2021-06-07 11:11:37.999 31680-31680/games.moisoni.evfp D/SurfaceControl: hide : mNativeObject = 531069881968 - sc.mNativeObject = 530532839920 - Surface(name=Surface(name=37630c6 InputMethod)/@0xd11e623 - animation-leash)/@0xd0fd5ff
2021-06-07 11:11:37.999 31680-31680/games.moisoni.evfp D/SurfaceControl: nativeSetFlags Done : Surface(name=Surface(name=37630c6 InputMethod)/@0xd11e623 - animation-leash)/@0xd0fd5ff
2021-06-07 11:11:38.001 31680-31680/games.moisoni.evfp I/SurfaceControl: release : mNativeObject = 530532840928 - Surface(name=Surface(name=a8e3812 NavigationBar0)/@0x38b32cd - animation-leash)/@0x2a3e45d / android.view.-$$Lambda$Rl1VZmNJ0VZDLK0BAbaVGis0rrA.accept:2 android.view.InsetsSourceControl.release:170 android.view.InsetsSourceConsumer.setControl:202 android.view.InsetsController.onControlsChanged:833 
2021-06-07 11:11:38.001 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject s[530532840928]
2021-06-07 11:11:38.001 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject e[530532840928]
2021-06-07 11:11:38.001 31680-31680/games.moisoni.evfp I/SurfaceControl: release : mNativeObject = 530532838464 - Surface(name=Surface(name=e511e35 StatusBar)/@0xbf071b - animation-leash)/@0xc4ac1d2 / android.view.-$$Lambda$Rl1VZmNJ0VZDLK0BAbaVGis0rrA.accept:2 android.view.InsetsSourceControl.release:170 android.view.InsetsSourceConsumer.setControl:202 android.view.InsetsController.onControlsChanged:833 
2021-06-07 11:11:38.001 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject s[530532838464]
2021-06-07 11:11:38.001 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject e[530532838464]
2021-06-07 11:11:38.185 31680-31680/games.moisoni.evfp I/ViewRootImpl@ef10be4[MainActivity]: stopped(true) old=false
2021-06-07 11:11:38.187 31680-31680/games.moisoni.evfp I/SurfaceControl: release : mNativeObject = 530532758608 - Surface(name=games.moisoni.evfp/games.moisoni.evfp.MainActivity$_31680)/@0xf744215 / android.view.ViewRootImpl.destroySurface:2484 android.view.ViewRootImpl.setWindowStopped:2332 android.view.WindowManagerGlobal.setStoppedState:741 android.app.Activity.performStop:8423 
2021-06-07 11:11:38.187 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject s[530532758608]
2021-06-07 11:11:38.187 31680-31680/games.moisoni.evfp I/SurfaceControl: nativeRelease nativeObject e[530532758608]
2021-06-07 11:11:38.202 31680-32437/games.moisoni.evfp W/libEGL: EGLNativeWindowType 0x7ca63be2a0 disconnect failed
2021-06-07 11:11:38.206 31680-31680/games.moisoni.evfp I/SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0xf744215 / android.view.SurfaceControl.readFromParcel:1115 android.view.IWindowSession$Stub$Proxy.relayout:1810 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9965 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995 
2021-06-07 11:11:38.206 31680-31680/games.moisoni.evfp I/SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0xda8bd8d / android.view.SurfaceControl.readFromParcel:1115 android.view.IWindowSession$Stub$Proxy.relayout:1820 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9965 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995 
2021-06-07 11:11:38.207 31680-31680/games.moisoni.evfp I/ViewRootImpl@ef10be4[MainActivity]: Relayout returned: old=(0,144,1440,3040) new=(0,144,1440,3040) req=(1440,2896)8 dur=4 res=0x5 s={false 0} ch=false fn=-1

在V4.0中,BillingClient方法回调后台线程中的调用,而不是主线程中的调用

解决方法是在BillingClient回调中将线程更改为Main


在UI线程中使用Toast调用您方法processPurchases()。

@研究员的回答是完全有效的选择,但对我来说,解决此问题的最佳方法是触发
主UI线程上的
侦听器,而不是更改所有
BillingClient
回调的线程

因为他发现了问题,所以他的答案仍会被接受

要在UI线程上调用
侦听器
,我创建了一个方法:

private Handler findUiHandler() {
        return new Handler(Looper.getMainLooper());
    }
然后像这样给听众打电话:

findUiHandler().post(() -> billingEventListener.onProductsFetched(fetchedSkuInfo));

跟踪日志的stacktraceI做到了。你能告诉我哪根线叫吐司吗?(Thread.currentThread().getName())
Log.d(“IapConnector”,“Thread:+Thread.currentThread().getName())在日志中打印此
Thread:PlayBillingLibrary-2
,我刚刚检查了
v3库中的代码,这里的线程是
Thread:main
,应该是。我不明白为什么
线程
从迁移到
v3库
变成了
v4库
,因为我只添加了一个循环来检查所有的skusthank,您已经进行了一些很好的调试。