背景
SDK/Android 源码里的API用java编写,程序员用kotlin扩展这些API时会遇到空判断难处理的边界问题。
具体业务背景
kotlin 重写GestureDetector的onFling时,由于父类java代码中onFling参数用@NonNull 源码级注解声明,导致kotlin重载时只能用非空类型。但是业务崩溃平台还会报NPE。
Parameter specified as non-null is null: method kotlin.jvm.internal.o.h, parameter e1
问题原因
listner调java方法时,即使参数为null,运行时不会报NPE,但调到kotlin代码后,参数的空检查就会报错.而此时我们如果把kotlin中的onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float)改成onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float) 则编译期不能通过继承的语法检查。
父类GestureDetector.SimpleOnGestureListener
public boolean onFling(@NonNull MotionEvent e1, @NonNull MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
子类kotlin重写
mGestureDetector = GestureDetectorCompat(requireActivity(), object : SimpleOnGestureListener() {
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
...
}
})
解决方法
用java子类包一层SDK里的代码,具体如下
GestureDetectorJavaDelegate.java
class GestureDetectorJavaDelegate extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(@Nullable MotionEvent e1, @Nullable MotionEvent e2, float velocityX, float velocityY) {
return super.onFling(e1, e2, velocityX, velocityY);
}
}
子类kotlin重写
mGestureDetector = GestureDetectorCompat(requireActivity(), object : GestureDetectorJavaDelegate() {
override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
...
}
})
kotlin和java混编时,还有比较容易出错的点:juejin.cn/post/723815…