0

我在构建代码的一部分时遇到了一些问题,该代码编辑服务器发送的缩略图并将它们呈现为 Google GroundOverlay。

这个问题似乎源于 Kotlin Coroutines。首先,谷歌的文档说地面覆盖层必须在主线程上创建。在主线程之外运行它们的创建会导致致命错误。所以我一直确保在主线程上制作这些GroundOverlays。但是,当尝试在 Main 之外的线程上创建位图时,我似乎根本没有覆盖。

class BarreMapFragment : Fragment(),
    GoogleMap.OnCameraIdleListener,
    GoogleMap.OnCameraMoveCanceledListener,
    GoogleMap.OnCameraMoveListener,
    GoogleMap.OnCameraMoveStartedListener,
    OnMapReadyCallback {

        //Main handler for google map/item styling
        googleMapHandler = GoogleMapHandler(gMap!!, activity!!.applicationContext, DefaultTheme, lifecycle.coroutineScope)


.    .    .

open class GoogleMapHandler(val gMap: GoogleMap,
                            val context: Context,
                            val mapThemeInstructions: MapThemeInstructions,
                            val coroutineScope: CoroutineScope
) {

fun updateActiveUserAvatarPosition(position: LatLng) {

        if (mActiveUserAvatar == null) {

            coroutineScope.launch {
                mActiveUserAvatar = mapObjectFactory.factory(
                    MapObject(
                        latitude = position.latitude,
                        longitude = position.longitude,
                        objectId = "SELF_AVATAR",
                        objectType = MapObjectType.USER_AVATAR,
                        timestamp = System.currentTimeMillis(),
                        weight = 20.toFloat()
                    ), getOverlayWidthByZoom(dpScreenWidth, gMap.cameraPosition.target, gMap.cameraPosition.zoom)) as RenderedUserAvatarItem
            }

        }

        mActiveUserAvatar?.updatePosition(position)
    }
    suspend fun factory(mapObject: MapObject, diameter: Float) : RenderedMapItem {

        overlayDiameter = diameter

        val item = RenderedUserAvatarItem(
            mapObject,
            buildOverlay(mapObject)
        )

        return item
    }

    @MainThread
    private suspend fun buildOverlay(mapObject: MapObject) : GroundOverlay {

        Log.d("UserOverlay", "I was called.")
        //Get the bitmap from the resources
        //TODO:  We can do more with this later...  Like custom avatars



        //val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.ic_user_avatar)
        val bitmap =  withContext(Dispatchers.Default) {
            async {
                val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
                val bitmap : Bitmap = drawableToBitmap(d)!!
                bitmap
            }
        }.await()

        //val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
        //val bitmap : Bitmap = drawableToBitmap(d)!!

        Log.d(TAG, "bitmap = " + bitmap.toString())

        //Make bitmap descriptor
        val descriptor = BitmapDescriptorFactory.fromBitmap(bitmap)

        val overlayOptions = GroundOverlayOptions().image(descriptor)

        //Position and size of groundoverlay
        overlayOptions.position(LatLng(mapObject.latitude, mapObject.latitude) , overlayDiameter)

        //Add the overlay to the map, get a handle and save it to public Overlay list
        val mOverlay = gMap.addGroundOverlay(overlayOptions)

        //Store the moment information in the overlay tag
        mOverlay.tag = mapObject.objectId

        return mOverlay
    }

从主线程调用挂起函数。现在,

        val bitmap =  withContext(Dispatchers.Unconfined) {
            async {
                val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
                val bitmap : Bitmap = drawableToBitmap(d)!!
                bitmap
            }
        }.await()

和上面注释掉的部分(不使用异步)

        val d: Drawable = context.getDrawable(R.drawable.ic_user_avatar)!!
        val bitmap : Bitmap = drawableToBitmap(d)!!

两者都会产生一个没有问题的 GroundOverlay。当我将 Dispatchers.Unconfined 更改为其他任何内容时,就会出现问题。甚至 Dispatchers.Main 也会导致 GroundOverlay 不显示在地图上。GroundOverlays 制作完成,我用日志语句检查了它们。他们的透明度是预期的,他们的知名度也是如此。问题似乎与位图有关。我怀疑我不理解 await() 的工作方式。我想它会暂停挂起功能,直到位图返回并准备好。

这是用于隔离错误的简化代码。我确实需要在 Dispatchers.Default 上完成此操作,因为每个缩略图的样式都会根据位置和一天中的时间进行调整。如果在主线程上完成,这部分处理在 UI 上会很困难。

4

0 回答 0