@@ -5,6 +5,7 @@ import android.graphics.Bitmap
5
5
import android.view.LayoutInflater
6
6
import android.view.View
7
7
import androidx.lifecycle.Lifecycle
8
+ import androidx.lifecycle.LifecycleOwner
8
9
import androidx.lifecycle.coroutineScope
9
10
import com.arcgismaps.ApiKey
10
11
import com.arcgismaps.ArcGISEnvironment
@@ -40,6 +41,9 @@ import io.flutter.plugin.common.EventChannel
40
41
import io.flutter.plugin.common.MethodCall
41
42
import io.flutter.plugin.common.MethodChannel
42
43
import io.flutter.plugin.platform.PlatformView
44
+ import kotlinx.coroutines.CoroutineScope
45
+ import kotlinx.coroutines.Dispatchers
46
+ import kotlinx.coroutines.SupervisorJob
43
47
import kotlinx.coroutines.cancel
44
48
import kotlinx.coroutines.launch
45
49
import java.io.ByteArrayOutputStream
@@ -57,8 +61,10 @@ internal class ArcgisMapView(
57
61
private val viewId : Int ,
58
62
private val mapOptions : ArcgisMapOptions ,
59
63
private val binding : FlutterPluginBinding ,
60
- private val lifecycle : Lifecycle ,
61
- ) : PlatformView {
64
+ override val lifecycle : Lifecycle ,
65
+ ) : PlatformView, LifecycleOwner {
66
+
67
+ private val coroutineScope = CoroutineScope (Dispatchers .Main .immediate + SupervisorJob ())
62
68
63
69
private val view: View = LayoutInflater .from(context).inflate(R .layout.vector_map_view, null )
64
70
private var mapView: MapView
@@ -97,23 +103,23 @@ internal class ArcgisMapView(
97
103
98
104
minScale = getMapScale(mapOptions.minZoom)
99
105
maxScale = getMapScale(mapOptions.maxZoom)
100
- lifecycle. coroutineScope.launch {
106
+ coroutineScope.launch {
101
107
loadStatus.collect(::onLoadStatusChanged)
102
108
}
103
109
}
104
110
105
111
mapView.map = map
106
112
mapView.graphicsOverlays.add(defaultGraphicsOverlay)
107
113
108
- lifecycle. coroutineScope.launch {
114
+ coroutineScope.launch {
109
115
mapView.mapScale.collect { scale ->
110
116
if (scale.isNaN()) return @collect
111
117
112
118
val zoomLevel = getZoomLevel(mapView)
113
119
zoomStreamHandler.addZoom(zoomLevel)
114
120
}
115
121
}
116
- lifecycle. coroutineScope.launch {
122
+ coroutineScope.launch {
117
123
mapView.viewpointChanged.collect {
118
124
// The viewpoint listener is executed async which means that the map
119
125
// can be altered when this is called. If we reload the map or dispose the map
@@ -149,7 +155,10 @@ internal class ArcgisMapView(
149
155
methodChannel.invokeMethod(" onStatusChanged" , status.jsonValue())
150
156
}
151
157
152
- override fun dispose () {}
158
+ override fun dispose () {
159
+ coroutineScope.cancel()
160
+ mapView.onDestroy(this )
161
+ }
153
162
154
163
// region helper
155
164
@@ -220,7 +229,7 @@ internal class ArcgisMapView(
220
229
}
221
230
222
231
private fun onStartLocationDisplayDataSource (result : MethodChannel .Result ) {
223
- lifecycle. coroutineScope.launch {
232
+ coroutineScope.launch {
224
233
mapView.locationDisplay.dataSource.start().onSuccess {
225
234
result.success(true )
226
235
}.onFailure { e ->
@@ -231,7 +240,7 @@ internal class ArcgisMapView(
231
240
232
241
233
242
private fun onStopLocationDisplayDataSource (result : MethodChannel .Result ) {
234
- lifecycle. coroutineScope.launch {
243
+ coroutineScope.launch {
235
244
mapView.locationDisplay.dataSource.stop().onSuccess {
236
245
result.success(true )
237
246
}.onFailure { e ->
@@ -280,7 +289,7 @@ internal class ArcgisMapView(
280
289
val provider = dataSource.currentProvider as CustomLocationProvider
281
290
val optionParams = call.arguments as Map <String , Any >
282
291
val position = optionParams.parseToClass<UserPosition >()
283
- lifecycle. coroutineScope.launch {
292
+ coroutineScope.launch {
284
293
provider.updateLocation(position)
285
294
result.success(true )
286
295
}
@@ -431,7 +440,7 @@ internal class ArcgisMapView(
431
440
return
432
441
}
433
442
val newScale = getMapScale(totalZoomLevel)
434
- lifecycle. coroutineScope.launch {
443
+ coroutineScope.launch {
435
444
mapView.setViewpointScale(newScale).onSuccess {
436
445
result.success(true )
437
446
}.onFailure { e ->
@@ -456,7 +465,7 @@ internal class ArcgisMapView(
456
465
return
457
466
}
458
467
val newScale = getMapScale(totalZoomLevel)
459
- lifecycle. coroutineScope.launch {
468
+ coroutineScope.launch {
460
469
mapView.setViewpointScale(newScale).onSuccess {
461
470
result.success(true )
462
471
}.onFailure { e ->
@@ -468,7 +477,7 @@ internal class ArcgisMapView(
468
477
469
478
private fun onRotate (call : MethodCall , result : MethodChannel .Result ) {
470
479
val angleDegrees = call.arguments as Double
471
- lifecycle. coroutineScope.launch {
480
+ coroutineScope.launch {
472
481
mapView.setViewpointRotation(angleDegrees).onSuccess {
473
482
result.success(true )
474
483
}.onFailure { e ->
@@ -518,7 +527,7 @@ internal class ArcgisMapView(
518
527
519
528
defaultGraphicsOverlay.graphics.addAll(newGraphic)
520
529
521
- lifecycle. coroutineScope.launch {
530
+ coroutineScope.launch {
522
531
updateMap().onSuccess { updateResult ->
523
532
result.success(updateResult)
524
533
}.onFailure { e ->
@@ -540,7 +549,7 @@ internal class ArcgisMapView(
540
549
541
550
// Don't use removeAll because this will not trigger a redraw.
542
551
graphicsToRemove.forEach(defaultGraphicsOverlay.graphics::remove)
543
- lifecycle. coroutineScope.launch {
552
+ coroutineScope.launch {
544
553
updateMap().onSuccess {
545
554
result.success(true )
546
555
}.onFailure { e ->
@@ -570,7 +579,7 @@ internal class ArcgisMapView(
570
579
}
571
580
572
581
val initialViewPort = Viewpoint (point.latitude, point.longitude, scale)
573
- lifecycle. coroutineScope.launch {
582
+ coroutineScope.launch {
574
583
mapView.setViewpointAnimated(
575
584
initialViewPort,
576
585
(animationOptions?.duration?.toFloat() ? : 0F ) / 1000 ,
@@ -603,7 +612,7 @@ internal class ArcgisMapView(
603
612
}, SpatialReference .wgs84()
604
613
)
605
614
606
- lifecycle. coroutineScope.launch {
615
+ coroutineScope.launch {
607
616
val viewpointResult = if (padding != null ) {
608
617
mapView.setViewpointGeometry(polyline.extent, padding)
609
618
} else {
@@ -633,7 +642,7 @@ internal class ArcgisMapView(
633
642
}
634
643
635
644
private fun onRetryLoad (result : MethodChannel .Result ) {
636
- lifecycle. coroutineScope.launch {
645
+ coroutineScope.launch {
637
646
mapView.map?.retryLoad()?.onSuccess {
638
647
result.success(true )
639
648
}?.onFailure { e ->
@@ -643,7 +652,7 @@ internal class ArcgisMapView(
643
652
}
644
653
645
654
private fun onExportImage (result : MethodChannel .Result ) {
646
- lifecycle. coroutineScope.launch {
655
+ coroutineScope.launch {
647
656
mapView.exportImage().onSuccess { bitmapResult ->
648
657
val bitmap = bitmapResult.bitmap
649
658
val stream = ByteArrayOutputStream ()
0 commit comments