小编Man*_*eko的帖子

Kotlin:延迟到val,或者是一个可以设置一次的var

只是好奇:在Kotlin中,我很想得到一些可以通过懒惰来初始化的val,但是有一个参数.那是因为我需要为了初始化它而创建的东西很晚.

具体来说,我希望我有:

private lateinit val controlObj:SomeView
Run Code Online (Sandbox Code Playgroud)

要么:

private val controlObj:SomeView by lazy { view:View->view.findViewById(...)}
Run Code Online (Sandbox Code Playgroud)

然后:

override fun onCreateView(....) {
    val view = inflate(....)


    controlObj = view.findViewById(...)
Run Code Online (Sandbox Code Playgroud)

或在第二种情况下controlObj.initWith(view)或类似的情况:

return view
Run Code Online (Sandbox Code Playgroud)

我无法使用,by lazy因为by lazy初始化时不会接受外部参数.在这个例子中 - 包含view.

当然我有,lateinit var但如果我能确保它在设置后变为只读,我会在一行中完成它会很好.

是否有一种非常干净的方法来创建只读初始化一次的只读变量,但只有当其他变量出生时?任何init once关键字?在init之后,编译器知道它是不可变的?

我知道这里存在潜在的并发问题,但如果我敢于在init之前访问它,我当然应该被抛出.

android immutability lazy-evaluation kotlin kotlin-lateinit

18
推荐指数
3
解决办法
6845
查看次数

谷歌地图:按坐标打开网址但显示位置名称

我一直在尝试从坐标 URL 打开 Google 地图(特别是在 Android 上,但不一定),例如

https://www.google.com/maps/search/?api=1&query=51.5055,-0.0754
Run Code Online (Sandbox Code Playgroud)

但是当地图打开时,我希望它显示位置名称,例如“塔桥”。不是坐标51.5055,-0.0754

我试过类似的东西

https://www.google.com/maps/search/?api=1&query=51.5055,-0.0754&query_place_id=Tower+Bridge
Run Code Online (Sandbox Code Playgroud)

没有运气。当地图打开时,它显示坐标,而不是地名。

我可以“注入”位置名称(类似 https://....&location_name=Traitors+Gate),和/或从坐标中显示位置名称(反向地理编码)的地图。

动机:坐标比位置名称更准确且更明确。例如,有俄亥俄州的耶路撒冷,还有半个地球之外的以色列耶路撒冷。或者,“卢浮宫”只是一栋建筑,但却是一座横跨四条街道的巨大建筑,有多个入口。坐标解决了这些问题,但它们不是“人类可读的”。您无法向用户显示“49.3697,0.8711”并期望他们识别奥马哈海滩。

谢谢

android google-maps reverse-geocoding google-maps-urls

6
推荐指数
1
解决办法
2837
查看次数

Android FusedLocationClient 不请求新样本

如何强制 FusedLocationProviderClient 显式请求新位置?

几个月前,我升级了 FusedLocationProviderClient。从那时起,要求在新地点进行采样将不会提供新的地点。

// Request a single location. 
//   Note: FusedLocationProviderClient.lastLocation
//   is no better
val request = LocationRequest()
                .setNumUpdates(1)
                .setExpirationDuration(0)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setMaxWaitTime(10*DateUtils.SECOND_IN_MILLIS)
                .setFastestInterval(0)
        fusedLocationClient?.requestLocationUpdates(request, object:LocationCallback() {
            override fun onLocationResult(result: LocationResult?) {
                super.onLocationResult(result)
                Log.v(LOG_TAG, "Single fused location request yields ${result?.lastLocation} ")
                callOnDone(result?.lastLocation)
            }
        }, Looper.getMainLooper())
Run Code Online (Sandbox Code Playgroud)

当我获取请求位置时,即使相隔几秒,它也会为我提供具有相同时间戳的相同位置。

我使用带有 GPX 记录轨迹的模拟器,这样 GPS 读数始终可用。

但是,当我尝试向位置管理器请求位置(并对结果不执行任何操作)时,效果要好得多。

(context?.getSystemService(Context.LOCATION_SERVICE) as? LocationManager)?
   .requestSingleUpdate(
       LocationManager.GPS_PROVIDER, 
       object :LocationListener{...dummy, just log the callback...},
       Looper.getMainLooper())
Run Code Online (Sandbox Code Playgroud)

结论:FusedLocationProviderClient 不会向操作系统请求新位置,即使在高优先级模式下也是如此。然而,如果外部有可用的位置,它确实接受新位置。

问题是:当我现在需要新位置时,如何强制FusedLocationProviderClient 主动请求新位置?

location google-api android-fusedlocation fusedlocationproviderclient

5
推荐指数
1
解决办法
1703
查看次数

Kotlinx.Serializer - 创建一个快速的 JSON 发送

我一直在玩 Kotlinx.serialisation。我一直在尝试找到一种使用 Kotlinx.serialisation 的快速方法来创建一个简单的 JSON(主要是将其发送出去),并且代码混乱。

对于一个简单的字符串,例如:

{"Album": "Foxtrot", "Year": 1972}
Run Code Online (Sandbox Code Playgroud)

我一直在做的是这样的:

val str:String = Json.stringify(mapOf(
        "Album" to JsonPrimitive("Foxtrot"),
        "Year" to JsonPrimitive(1972)))
Run Code Online (Sandbox Code Playgroud)

这远不是很好。我的元素大多是原始的,所以我希望我有这样的东西:

val str:String = Json.stringify(mapOf(
   "Album" to "Sergeant Pepper",
   "Year" to 1967))
Run Code Online (Sandbox Code Playgroud)

此外,我很高兴有一个带有嵌套 JSON 的解决方案。就像是:

Json.stringify(JsonObject("Movies", JsonArray(
   JsonObject("Name" to "Johnny English 3", "Rate" to 8),
   JsonObject("Name" to "Grease", "Rate" to 1))))
Run Code Online (Sandbox Code Playgroud)

那会产生:

{
  "Movies": [
    {
      "Name":"Johnny English 3",
      "Rate":8
    },
    {
      "Name":"Grease",
      "Rate":1
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

(不一定美化,甚至更好)

有这样的吗?

注意:使用序列化器很重要,而不是直接的字符串,例如

"""{"Name":$name, "Val": $year}"""
Run Code Online (Sandbox Code Playgroud)

因为连接字符串是不安全的。任何非法字符都可能会破坏 JSON!我不想处理转义非法字符:-(

谢谢

json kotlin kotlinx.serialization

4
推荐指数
1
解决办法
1987
查看次数