【问题标题】:GMS Task<TResult> class: can getResult() return null if isSuccessful()?GMS Task<TResult> 类:如果 isSuccessful(),getResult() 能否返回 null?
【发布时间】:2018-11-13 22:08:21
【问题描述】:

最近对 GMS 任务库进行了 @Nullable 更改。反编译的.class的前几行看起来像

public abstract class Task<TResult> {
    public Task() {
    }

    public abstract boolean isComplete();

    public abstract boolean isSuccessful();

    public abstract boolean isCanceled();

    @Nullable
    public abstract TResult getResult();

我之前编译的 Kotlin 代码:

        if (task.isSuccessful) {
            task.result.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
                this.emailIdTokenCompleteListener()(taskk)
            }

更新一些 gms play-services-zzz 依赖后,代码现在出现编译错误:

LoginActivity.kt: (148, 28): 在 AuthResult 类型的可空接收器上只允许安全 (?.) 或非空断言 (!!.) 调用?

问题是,isSuccessful() == true 是否暗示getResult != null?还是将 if 测试更改为 if (task.result != null) 会更好?

【问题讨论】:

    标签: android kotlin google-play-services


    【解决方案1】:

    您看到的是 Kotlin 编译器未能根据 isSuccessful 的结果将结果智能转换为 NonNull 类型,这可能在与 Java 和 Kotlin 代码交互时发生。

    在 Kotlin 1.3 中,语言中添加了“合同”的实现,以允许开发人员以 IDE 可用于静态分析和推断类型(智能转换)的格式添加有关方法的元数据。

    请参阅第 1.2 节“返回和暗示”https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c

    因此,如果实现看起来像这样,它会正确地进行智能转换:

    open class Task<T> {
        var result: T? = null
            private set
    
        fun isSuccessful(): Boolean {
            contract {
                returns(true) implies (result != null)
            }
            return result != null
        }
    }
    

    但是,在您的情况下,您可能希望使用另一个安全调用运算符 ? 并使用 Elvis 运算符 ?: 调用您的 !task.isSuccessful 代码,如下所示:

    if (task.isSuccessful) {
            task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
                this.emailIdTokenCompleteListener()(taskk)
            } ?: handleFailure() // Defensively call just in case
    } else {
        handleFailure()
    }
    

    【讨论】:

      【解决方案2】:

      有些 GMS 任务可以在运行时返回 null。例如FirebaseAnalytics.getAppInstanceId()

      所以你应该检查结果是否为空,而不是依赖注释。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-07
        • 1970-01-01
        相关资源
        最近更新 更多