相关文章推荐
文雅的跑步鞋  ·  解决 WPF ...·  2 天前    · 
想表白的四季豆  ·  List<string> ...·  1 周前    · 
知识渊博的柠檬  ·  WPF ...·  3 周前    · 
喝醉的铁板烧  ·  Intro to JaCoCo | ...·  1 月前    · 
阳刚的硬盘  ·  System.Data.SqlClient. ...·  1 年前    · 
忧郁的日光灯  ·  Axios和Promise方法 - ...·  1 年前    · 

null不能被转换为非空类型 kotlin.collection.List<com.android.billingclient.api.Purchase>。

1 人不认可

我的大多数应用程序的用户都没有遇到任何崩溃。然而,我的一些应用程序用户得到了这个致命的异常。

Fatal Exception: java.lang.NullPointerException: null cannot be cast to non-null type kotlin.collections.List<com.android.billingclient.api.Purchase>
       at com.company.appname.ActivityClass$loadAllSKUs$1.onSkuDetailsResponse(ActivityClass.java:10)
       at com.android.billingclient.api.zzj.run(zzj.java:7)
       at android.os.Handler.handleCallback(Handler.java:873)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:226)
       at android.app.ActivityThread.main(ActivityThread.java:7178)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:942)

这是我的代码。我用它来查看一个用户是否已经购买了应用内购买。如果他没有,就启动计费流程。

  private lateinit var billingClient: BillingClient
  private val skuList = listOf("product")
  private boolean isOwned = false
  private fun loadAllSKUs() {
    if (billingClient.isReady)
      val params = SkuDetailsParams.newBuilder()
              .setSkusList(skuList)
              .setType(BillingClient.SkuType.INAPP)
              .build()
      billingClient.querySkuDetailsAsync(params) { billingResult, skuDetailsList ->
        if (skuDetailsList != null)
          if (billingResult.responseCode === BillingClient.BillingResponseCode.OK && !skuDetailsList.isEmpty())
            for (skuDetailsObject in skuDetailsList)
              val skuDetails = skuDetailsObject
              if (skuDetails.sku.equals("product"))
                val result: Purchase.PurchasesResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP)
                val purchases: List<Purchase> = result.getPurchasesList() as List<Purchase>
                for (purchase in purchases)
                  val thisSKU = purchase.sku
                  if (thisSKU == "product")
                    isOwned = true;
                    // System.out.println("OWNED")
if(isOwned == false){
                    val billingFlowParams = BillingFlowParams
                            .newBuilder()
                            .setSkuDetails(skuDetails)
                            .build()
                    billingClient.launchBillingFlow(this@ActivityClass, billingFlowParams)

请告诉我如何解决这个问题,谢谢。This question得到同样的错误,但显然还没有找到修复方法。

3 个评论
替换代码0】是空的,而你把它投给了非空类型的 List<Purchase> ,这导致了这个问题。
@NongthonbamTonthoi 我理解。但是,为什么这种情况发生在某些设备上,而不是所有的设备?我怎样才能解决这个问题呢?谢谢。
"为什么这发生在某些设备上,而不是所有的设备",如果不知道你正在处理的API,就无法回答。"我怎样才能解决这个问题?"这取决于。1.你为什么首先要铸造( as List<Purchase> )?2.如果你在那里得到 null ,你想做什么?
android
kotlin
in-app-purchase
android-inapp-purchase
Bandy
Bandy
发布于 2020-09-23
2 个回答
IlTera
IlTera
发布于 2020-09-25
已采纳
0 人赞同

Kotlin的表现力比很多层叠式的if...

另外,Kollin在编译时处理无效性,所以IDE应该通知你是否为空。

我试图重写你的代码,因为它非常不容易调试。 老实说,我不知道它是否有效,是否做了同样的事情(它应该如此,但正如我所说的,所有这些都很难理解),但我发现它更容易阅读和调试。

请记住,为了删除所有的if !=null,你可以使用? 操作符。

希望它能帮助你理解Kotlin的表达性

private fun loadAllSKUs() {
    billingClient.takeIf{it.isReady}
    ?.let {
    val params = SkuDetailsParams.newBuilder()
            .setSkusList(skuList)
            .setType(BillingClient.SkuType.INAPP)
            .build()
    billingClient.querySkuDetailsAsync(params) { billingResult, skuDetailsList ->
    skuDetailsList
        ?.takeIf{ billingResult.responseCode === BillingClient.BillingResponseCode.OK && skuDetailsList.isNotEmpty() }
        ?.filter {it.sku.equals("product")}
        ?.forEach { skuDetails -> 
            val result: Purchase.PurchasesResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP)
            val purchases: List<Purchase>? = result.getPurchasesList() as? List<Purchase>
            val isOwned = purchases?.any { it.sku == "product" }?:false
            if(!isOwned){
                val billingFlowParams = BillingFlowParams
                        .newBuilder()
                        .setSkuDetails(skuDetails)
                        .build()
                billingClient.launchBillingFlow(skuDetails@ActivityClass, billingFlowParams)
    
这段代码比较整齐,但我不认为它解决了我在某些设备上遇到的问题。
有评论说,这是因为 result.getPurchasesList() 是空的,而我把它投给了非空类型的 List<Purchase>
另外,我在第二行得到 Unresolved reference: it
I've edited the snippet with a cast to null for List<Purchase> I think you should look into Kotlin lang reference kotlinlang.org/docs/reference
GnoSiS
GnoSiS
发布于 2020-09-25
0 人赞同

如前所述,该错误指向 result.getPurchasesList() 的强制铸造。