6
6
7
7
import android .Manifest ;
8
8
import android .annotation .SuppressLint ;
9
+ import android .app .Activity ;
10
+ import android .app .Application ;
9
11
import android .content .Context ;
10
12
import android .content .pm .PackageManager ;
11
13
import android .graphics .Bitmap ;
17
19
import androidx .annotation .Nullable ;
18
20
import androidx .lifecycle .DefaultLifecycleObserver ;
19
21
import androidx .lifecycle .Lifecycle ;
22
+ import androidx .lifecycle .Lifecycle .State ;
20
23
import androidx .lifecycle .LifecycleOwner ;
21
24
import com .google .android .gms .maps .CameraUpdate ;
22
25
import com .google .android .gms .maps .GoogleMap ;
36
39
import io .flutter .plugin .common .BinaryMessenger ;
37
40
import io .flutter .plugin .common .MethodCall ;
38
41
import io .flutter .plugin .common .MethodChannel ;
42
+ import io .flutter .plugin .common .PluginRegistry ;
39
43
import io .flutter .plugin .platform .PlatformView ;
40
44
import java .io .ByteArrayOutputStream ;
41
45
import java .util .ArrayList ;
46
50
47
51
/** Controller of a single GoogleMaps MapView instance. */
48
52
final class GoogleMapController
49
- implements DefaultLifecycleObserver ,
53
+ implements Application .ActivityLifecycleCallbacks ,
54
+ DefaultLifecycleObserver ,
50
55
ActivityPluginBinding .OnSaveInstanceStateListener ,
51
56
GoogleMapOptionsSink ,
52
57
MethodChannel .MethodCallHandler ,
@@ -70,8 +75,12 @@ final class GoogleMapController
70
75
private boolean disposed = false ;
71
76
private final float density ;
72
77
private MethodChannel .Result mapReadyResult ;
78
+ @ Nullable private final Lifecycle lifecycle ;
73
79
private final Context context ;
74
- private final LifecycleProvider lifecycleProvider ;
80
+ // Do not use directly, use getApplication() instead to get correct application object for both v1
81
+ // and v2 embedding.
82
+ @ Nullable private final Application mApplication ;
83
+ @ Nullable private final PluginRegistry .Registrar registrar ; // For v1 embedding only.
75
84
private final MarkersController markersController ;
76
85
private final PolygonsController polygonsController ;
77
86
private final PolylinesController polylinesController ;
@@ -85,7 +94,9 @@ final class GoogleMapController
85
94
int id ,
86
95
Context context ,
87
96
BinaryMessenger binaryMessenger ,
88
- LifecycleProvider lifecycleProvider ,
97
+ @ Nullable Application application ,
98
+ @ Nullable Lifecycle lifecycle ,
99
+ @ Nullable PluginRegistry .Registrar registrar ,
89
100
GoogleMapOptions options ) {
90
101
this .id = id ;
91
102
this .context = context ;
@@ -94,7 +105,9 @@ final class GoogleMapController
94
105
this .density = context .getResources ().getDisplayMetrics ().density ;
95
106
methodChannel = new MethodChannel (binaryMessenger , "plugins.flutter.io/google_maps_" + id );
96
107
methodChannel .setMethodCallHandler (this );
97
- this .lifecycleProvider = lifecycleProvider ;
108
+ mApplication = application ;
109
+ this .lifecycle = lifecycle ;
110
+ this .registrar = registrar ;
98
111
this .markersController = new MarkersController (methodChannel );
99
112
this .polygonsController = new PolygonsController (methodChannel , density );
100
113
this .polylinesController = new PolylinesController (methodChannel , density );
@@ -106,8 +119,30 @@ public View getView() {
106
119
return mapView ;
107
120
}
108
121
109
- void init () {
110
- lifecycleProvider .getLifecycle ().addObserver (this );
122
+ void init (State lifecycleState ) {
123
+ switch (lifecycleState ) {
124
+ case RESUMED :
125
+ mapView .onCreate (null );
126
+ mapView .onStart ();
127
+ mapView .onResume ();
128
+ break ;
129
+ case STARTED :
130
+ mapView .onCreate (null );
131
+ mapView .onStart ();
132
+ break ;
133
+ case CREATED :
134
+ mapView .onCreate (null );
135
+ break ;
136
+ case DESTROYED :
137
+ case INITIALIZED :
138
+ // Nothing to do, the activity has been completely destroyed or not yet created.
139
+ break ;
140
+ }
141
+ if (lifecycle != null ) {
142
+ lifecycle .addObserver (this );
143
+ } else {
144
+ getApplication ().registerActivityLifecycleCallbacks (this );
145
+ }
111
146
mapView .getMapAsync (this );
112
147
}
113
148
@@ -472,10 +507,7 @@ public void dispose() {
472
507
methodChannel .setMethodCallHandler (null );
473
508
setGoogleMapListener (null );
474
509
destroyMapViewIfNecessary ();
475
- Lifecycle lifecycle = lifecycleProvider .getLifecycle ();
476
- if (lifecycle != null ) {
477
- lifecycle .removeObserver (this );
478
- }
510
+ getApplication ().unregisterActivityLifecycleCallbacks (this );
479
511
}
480
512
481
513
private void setGoogleMapListener (@ Nullable GoogleMapListener listener ) {
@@ -505,7 +537,64 @@ public void onInputConnectionUnlocked() {
505
537
// TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 is fixed in stable.
506
538
}
507
539
508
- // DefaultLifecycleObserver
540
+ // Application.ActivityLifecycleCallbacks methods
541
+ @ Override
542
+ public void onActivityCreated (Activity activity , Bundle savedInstanceState ) {
543
+ if (disposed || activity .hashCode () != getActivityHashCode ()) {
544
+ return ;
545
+ }
546
+ mapView .onCreate (savedInstanceState );
547
+ }
548
+
549
+ @ Override
550
+ public void onActivityStarted (Activity activity ) {
551
+ if (disposed || activity .hashCode () != getActivityHashCode ()) {
552
+ return ;
553
+ }
554
+ mapView .onStart ();
555
+ }
556
+
557
+ @ Override
558
+ public void onActivityResumed (Activity activity ) {
559
+ if (disposed || activity .hashCode () != getActivityHashCode ()) {
560
+ return ;
561
+ }
562
+ mapView .onResume ();
563
+ }
564
+
565
+ @ Override
566
+ public void onActivityPaused (Activity activity ) {
567
+ if (disposed || activity .hashCode () != getActivityHashCode ()) {
568
+ return ;
569
+ }
570
+ mapView .onPause ();
571
+ }
572
+
573
+ @ Override
574
+ public void onActivityStopped (Activity activity ) {
575
+ if (disposed || activity .hashCode () != getActivityHashCode ()) {
576
+ return ;
577
+ }
578
+ mapView .onStop ();
579
+ }
580
+
581
+ @ Override
582
+ public void onActivitySaveInstanceState (Activity activity , Bundle outState ) {
583
+ if (disposed || activity .hashCode () != getActivityHashCode ()) {
584
+ return ;
585
+ }
586
+ mapView .onSaveInstanceState (outState );
587
+ }
588
+
589
+ @ Override
590
+ public void onActivityDestroyed (Activity activity ) {
591
+ if (disposed || activity .hashCode () != getActivityHashCode ()) {
592
+ return ;
593
+ }
594
+ destroyMapViewIfNecessary ();
595
+ }
596
+
597
+ // DefaultLifecycleObserver and OnSaveInstanceStateListener
509
598
510
599
@ Override
511
600
public void onCreate (@ NonNull LifecycleOwner owner ) {
@@ -549,7 +638,6 @@ public void onStop(@NonNull LifecycleOwner owner) {
549
638
550
639
@ Override
551
640
public void onDestroy (@ NonNull LifecycleOwner owner ) {
552
- owner .getLifecycle ().removeObserver (this );
553
641
if (disposed ) {
554
642
return ;
555
643
}
@@ -760,6 +848,24 @@ private int checkSelfPermission(String permission) {
760
848
permission , android .os .Process .myPid (), android .os .Process .myUid ());
761
849
}
762
850
851
+ private int getActivityHashCode () {
852
+ if (registrar != null && registrar .activity () != null ) {
853
+ return registrar .activity ().hashCode ();
854
+ } else {
855
+ // TODO(cyanglaz): Remove `getActivityHashCode()` and use a cached hashCode when creating the view for V1 embedding.
856
+ // https://github.com/flutter/flutter/issues/69128
857
+ return -1 ;
858
+ }
859
+ }
860
+
861
+ private Application getApplication () {
862
+ if (registrar != null && registrar .activity () != null ) {
863
+ return registrar .activity ().getApplication ();
864
+ } else {
865
+ return mApplication ;
866
+ }
867
+ }
868
+
763
869
private void destroyMapViewIfNecessary () {
764
870
if (mapView == null ) {
765
871
return ;
0 commit comments