Kotlin:捕获到一个封闭在捕获中时要修改的参考对象中

时间:2019-01-09 18:00:01

标签: android firebase kotlin firebase-cloud-messaging token

我正在使用Kotlin在Android上实现Firebase。

FirebaseInstanceId.getInstance().token被贬值时,我在MyFirebaseMessageService类的伴随对象内使用以下函数来获取令牌:

companion object
{
  fun grabFcmToken():String?
  {
    var s:String?=null
    FirebaseInstanceId.getInstance().
    instanceId.addOnCompleteListener {task ->
    if (task.isSuccessful)
     {
        s=task.result!!.token
        Log.i("token used is ", s)
     }
     else
      {
        throw Exception("Can't get firebase token")
      } 
    }
    Log.i("To be returned token ", s)
    return s
  }
}

Android Studio将s突出显示为Wrapped into a reference object to be modified when captured in a closure

在执行grabFcmToken()后,第一个日志成功打印了令牌,但是第二个日志中有一个java.lang.NullPointerException: println needs a message,指示s的值为null,因此其值不变。 / p>

我如何修改s以便捕获的令牌反映在其中?

2 个答案:

答案 0 :(得分:0)

这里的事情是,第一个日志位于异步的侦听器中。任务。所以大概是这样的:

  1. 致电grabFcmToken()
  2. FirebaseInstanceId.getInstance().instanceId被调用。在这里,获取instanceId的任务开始。因此,您还放置了一个侦听器。由于这是异步任务,因此代码不需要等待,因此它可以继续进行。
  3. Log.i("To be returned token ", s)snull的地方运行。 NPE在这里。

我建议更改功能以改为返回任务或具有侦听器参数(第一个参数似乎更好)。像这样:

companion object {
        fun requestPushToken(): Task<InstanceIdResult> {
            return FirebaseInstanceId.getInstance().instanceId
        }
}

然后从您需要的任何类中调用它:

class SampleActivity: AppCompatActivity(){

    YourAppService.requestPushToken().addCompleteListener { task ->
        if (task.isSuccessful){
            // TODO: Handle
        } else {
            // TODO: Handle
        }
    }

}

答案 1 :(得分:0)

所以。离开这个职位后,我有些顿悟。当前的答案实际上并没有帮助,但是有些点击。

companion object {
  fun grabFcmToken():String? {
    var s:String? = null // !!!!! s is defined here

    FirebaseInstanceId.getInstance().
      instanceId.addOnCompleteListener {task ->
        if (task.isSuccessful) {
          s = task.result!!.token // !!!!!! s is redefined inside here

          Log.i("token used is ", s)
        } else {
          throw Exception("Can't get firebase token")
        } 
      }

    Log.i("To be returned token ", s)

    // !!!!!! s is never changed after the redefine
    return s
  }
}

第三组超兴奋!!!!是重要的一组。因为我们从未在其他任何地方更新s的状态,所以出现了此问题。我说这个问题是因为我讨厌我的IDE告诉我一些不正确的信息。所以我想知道为什么会这样。我几乎完全同意这一点。但。在您的情况下,没有真正简单的方法可以更改此回报。我不是1000%的人会按照我的方式进行操作,但同时看起来像这样。

总体而言,如果您可以按照以下方式做点事情::

instanceId.addOnCompleteListener { task ->
  val newS = "s"
  if(task.isSuccessful) {
    newS = task.result!!.token // this might give errors, but I think you get the point
  }

  return newS
}

无关紧要的警告会消失。