Open psy0rz opened 1 year ago
@psy0rz Thank you for opening this issue. 🙏 Please check out these other resources that might help you get to a resolution in the meantime:
google-maps
tagThis is an automated message, feel free to ignore.
note that getCellSize is just a calculation, so its sideeffect free.
although i should probably move those calculations to the overlays function?
hmm i think this method is wrong anyway: My slow function is called for every cell everytime, instead of only to remove/add new cells. Ill implement it as one big image, instead of several tiles, probably avoiding the crash as well.
@psy0rz Could you let me know if you are creating Bitmap per recomposition? I couldn't see any caching mechanism or async Bitmap creation operation, which can block your UI thread and cause the app to freeze.
for now i am, just as test. its fast enough, but at a certain moment it just freezes forever.
(i have to say i worked around this by just composing one groundoverlay, but i still want to know why this happens)
@psy0rz let's try this code and see if it freezes again or not.
var bitmapDescriptor: BitmapDescriptor?=null
fun getrect(): BitmapDescriptor {
if (bitmapDescriptor!=null){
return bitmapDescriptor
}
val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
borderPaint.style = Paint.Style.STROKE
borderPaint.alpha = 128
borderPaint.strokeWidth = 10f
borderPaint.color = Color.RED
var bitmapborder = Bitmap.createBitmap(
(512).toInt(),
(512).toInt(), Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmapborder)
canvas.drawRect(
0f, 0f, 512f, 512f,
borderPaint
)
borderPaint.color = Color.GREEN
canvas.drawLine(20f, 20f, 490f, 490f, borderPaint)
var bitmap = BitmapDescriptorFactory.fromBitmap(bitmapborder)
bitmapborder.recycle()
bitmapDescriptor = bitmap
return bitmap
}
I've changed the code to create the Bitmap just once, please test this code instead of your current getrect()
method or use remember api.
Hi @psy0rz ,
As pointed out by @aabolfazl , the bitmap is probably abusing the recomposition, and hence the fall in performance.
Thanks.
@kikoso could you please re-open this issue? I have a reproducible sample.
My usecase: adding text-labels to a map that should rotate and scale with the map. ie. "locker-room", "toilet" etc. My idea was to draw these to a bitmap and add them to to the map this way. There may me about 30 such text labels added to the map. Please advice also if some other Composable / construct should be used instead for this usecase.
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.CameraPosition
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.compose.GoogleMap
import com.google.maps.android.compose.GroundOverlay
import com.google.maps.android.compose.GroundOverlayPosition
import com.google.maps.android.compose.rememberCameraPositionState
@Composable
fun GroundOverlayANR() = Box(
modifier = Modifier
.fillMaxSize()
) {
val rijksmuseum = LatLng(52.3600866, 4.8857052)
val cameraPositionState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(rijksmuseum, 17f)
}
GoogleMap(
modifier = Modifier.fillMaxSize(),
cameraPositionState = cameraPositionState
) {
for (idx in 0 until 100) { // change the upper limit to 1 to make the problem go away
GroundOverlay(
position = GroundOverlayPosition.create(
rijksmuseum,
50f,
50f
),
image = getrect(),
zIndex = 1000f
)
}
}
}
var bitmapDescriptor: BitmapDescriptor? = null
fun getrect(): BitmapDescriptor {
Log.d("GROUNDOVERLAY", "getrect START")
bitmapDescriptor?.let {
Log.d("GROUNDOVERLAY", "getrect REUSE")
return it
}
val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
borderPaint.style = Paint.Style.STROKE
borderPaint.alpha = 128
borderPaint.strokeWidth = 10f
borderPaint.color = Color.RED
var bitmapborder = Bitmap.createBitmap(
(512).toInt(),
(512).toInt(), Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmapborder)
canvas.drawRect(
0f, 0f, 512f, 512f,
borderPaint
)
borderPaint.color = Color.GREEN
canvas.drawLine(20f, 20f, 490f, 490f, borderPaint)
var bitmap = BitmapDescriptorFactory.fromBitmap(bitmapborder)
bitmapborder.recycle()
bitmapDescriptor = bitmap
Log.d("GROUNDOVERLAY", "getrect DONE")
return bitmap
}
I just noticed I was running 4.3.3, and updating to 6.1.0 seems to have resolved the issue.
I'm very sorry to bother.
Leaving this here for anyone else running into this.
I found a way to reproduce this again in 6.1.0
It happens when removing items from the map; I think GroundOverlay and Markers are affected.
An in-progress camera move/animation might be the triggering factor that causes a deadlock.
I think I could produce an example project.
In short, the combination of these events triggers an ANR, I think:
May be related to https://github.com/googlemaps/android-maps-compose/issues/391
I'm new to Android SDK, so maybe i'm making a rookie mistake.
This is my composable:
getrect is just a simple temporary test thing:
Using it in a GoogleMap like this:
This works perfectly, but after moving the map a while, the app suddenly freezes. Sometimes pretty quickly, sometimes it takes like 10-20 seconds.
This is the last log output:
After that last return the app hangs and i get the 'app isnt responding' popup.
Tried to update everything to the latest versions to no avail:
Am i using it wrong, or am i triggering some unkown bug due to the intensity of adding/removing groundoverlays?