它說Location是@NonNull,但實際上作業系統有時確實會回傳null,這使應用程式崩潰。
object : LocationListener {
override fun onLocationChanged(location: Location) {
doSomethingWithLocation(location) //App crashes here, because location is null {
}
}
是否有辦法告訴編譯器Location實際上是Location??
uj5u.com熱心網友回復:
我不相信有辦法丟棄來自java的nullability資訊。在你的案例中,這是一個問題,因為正如@RobCo所指出的,kotlin會自動為location插入非null的斷言,而斷言會失敗。
因此,你剩下的唯一解決方案是使用一個java包裝器型別,它將只為你提供非空的位置值,你可以在你的kotlin代碼中使用它。
import androidx.core.util.Consumer;
public class LocationHandler{
LocationHandler(Consumer<Location> delegate){
this.delegate = delegate;
}
private Consumer<Location> delegate;
private LocationListener _listener = new LocationListener() {
@Override[/span
public void onLocationChanged(@NonNull Location Location) {
//只轉發非空的位置值。
if(location != null){ delegate.accept(location); }
else {
Log.d("LocationHandler", "Received null Location") 。
}
}
};
public LocationListener getListener(){
return _listener;
}
}
現在在你的kotlin代碼中,你可以將其作為
使用class MainActivity : AppCompatActivity() {
private val locationDelegate = Consumer< Location> {
//對非空的位置做一些事情。
}
override fun somFun {
val locationHandler = LocationHandler(locationDelegate)
val locMan = getSystemService(Context.LOCATION_SERVICE) as LocationManager
locMan.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0L,
0F,
locationHandler.listener)
}
}
uj5u.com熱心網友回復:
我發現了兩個變通的方法。
首先,如果介面只包含一個抽象方法,我們可以使用SAM轉換,并將引數的型別覆寫為Location?,像這樣:
val listener = LocationListener { location: Location? ->
doSomethingWithLocation(location)
}
有趣的是,如果使用SAM轉換,我們可以重寫引數,但如果使用子型別的完整語法,我們就不能。看起來LocationListener是SAM的,所以這個解決方案在你的案例中是可行的。
如果第一個解決方案不可行,我們可以在Java中重寫介面:
public interface MyLocationListener extends LocationListener {
@Override
void onLocationChanged(@Nullable Location location)。
val listener = object : MyLocationListener {
override fun onLocationChanged(location: Location?
doSomethingWithLocation(location)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/328860.html
標籤:

