错误的可空注释:在 Kotlin 上有什么方法可以克服这个问题,或者我应该使用 Java 作为解决方法吗?

and*_*per 10 java android kotlin gesture-detection

背景

我在 Android 上从事一些大型项目,该项目最初 100% 用 Ja​​va 编写。当我将一些文件转换为 Kotlin 时,我发现至少有 2 种情况文档和代码声明某些函数的某些参数应该为非空,因此我也让它们在 Kotlin 上保持这种方式:

这意味着它们看起来像这样:

boolean onFling(@NonNull MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY);
Run Code Online (Sandbox Code Playgroud)

问题

我通过 Crashlytics 注意到,这两种情况实际上会导致某些设备崩溃,因为它们实际上获取的是 null 值,因为 Kotlin 对此类事情非常严格(当参数设置为非 null 时获取 null)。

我尝试过的

我已经在问题跟踪器(此处和此处)上报告了这一点,并且我尝试找到如何强制 Kotlin 允许参数可以为空,尽管背后的代码表明它们不能为空。可悲的是,它总是会导致“'onFling'覆盖任何内容”的错误,并且不会让我构建它。

我不知道如何做,所以现在我使用 Java。意思是这样的:

public class SimpleOnGestureListenerCompat extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onFling(@Nullable final MotionEvent e1, @Nullable final MotionEvent e2, final float velocityX, final float velocityY) {
        return super.onFling(e1, e2, velocityX, velocityY);
    }
}
Run Code Online (Sandbox Code Playgroud)

我还添加了 Crashlytics 来告诉我第二个参数是否也可以为 null,这就是为什么我也将其设置为可以为 null。

问题

  1. 这是我现在可以使用的唯一解决方法吗?我不能用 Kotlin 来实现这个吗?也许使用一些注释来删除我将要创建的新类在运行时的可空检查,从而扩展这些有问题的类?
  2. 允许这样做只是因为 Android Studio 不能很好/严格地处理 Java 的可空性,还是预计这始终是 Java 的可能解决方法?它甚至没有向我显示使用错误注释的警告

use*_*624 1

我在 Java 中创建了自己的 SimpleOnGestureListener(名为 KotlinAdapterOnGestureListener)作为便利类,然后我可以使用 Kotlin 来实现真正的 OnGestureListener,扩展 KotlinAdapterOnGestureListener 并覆盖 onMoveKt 和 onFlingKt,而不是 onMove 和 onFling:

public class KotlinAdapterOnGestureListener implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {

    public boolean onSingleTapUp(@NonNull MotionEvent e) {
        return false;
    }

    public void onLongPress(@NonNull MotionEvent e) {
    }

    /** Instead of overwriting this method, overwrite onScrollKt, because despite
     * the annotation, the parameter e1 is sometimes null. */
    final public boolean onScroll(@NonNull MotionEvent e1, @NonNull MotionEvent e2,
                            float distanceX, float distanceY) {
        return onScrollKt(e1, e2, distanceX, distanceY);
    }

    public boolean onScrollKt(MotionEvent e1, MotionEvent e2,
                            float distanceX, float distanceY) {
        return false;
    }

    /** Instead of overwriting this method, overwrite onFlingKt, because despite
     * the annotation, the parameter e1 is sometimes null. */
    final public boolean onFling(@NonNull MotionEvent e1, @NonNull MotionEvent e2, float velocityX,
                           float velocityY) {
        return onFlingKt(e1, e2, velocityX, velocityY);
    }

    public boolean onFlingKt(MotionEvent e1, MotionEvent e2,
                              float velocityX, float velocityY) {
        return false;
    }

    public void onShowPress(@NonNull MotionEvent e) {
    }

    public boolean onDown(@NonNull MotionEvent e) {
        return false;
    }

    public boolean onDoubleTap(@NonNull MotionEvent e) {
        return false;
    }

    public boolean onDoubleTapEvent(@NonNull MotionEvent e) {
        return false;
    }

    public boolean onSingleTapConfirmed(@NonNull MotionEvent e) {
        return false;
    }

}
Run Code Online (Sandbox Code Playgroud)

至少,如果您有多个 OnGestureListener,那么您只需要在 Java 中使用这一类,而您的“真正”编码仍然在 Kotlin 中。