@@ -85,11 +85,92 @@ public void onActivityDestroyed(Activity activity) {
8585 @ Override
8686 public void onActivityStopped (Activity activity ) {
8787 if (thisActivity == activity ) {
88- delegate .saveStateBeforeResult ();
88+ activityState . getDelegate () .saveStateBeforeResult ();
8989 }
9090 }
9191 }
9292
93+ private class ActivityState {
94+ private Application application ;
95+ private Activity activity ;
96+ private ImagePickerDelegate delegate ;
97+ private MethodChannel channel ;
98+ private LifeCycleObserver observer ;
99+ private ActivityPluginBinding activityBinding ;
100+
101+ // This is null when not using v2 embedding;
102+ private Lifecycle lifecycle ;
103+
104+ ActivityState (
105+ final Application application ,
106+ final Activity activity ,
107+ final BinaryMessenger messenger ,
108+ final MethodChannel .MethodCallHandler handler ,
109+ final PluginRegistry .Registrar registrar ,
110+ final ActivityPluginBinding activityBinding ) {
111+ this .application = application ;
112+ this .activity = activity ;
113+ this .activityBinding = activityBinding ;
114+
115+ delegate = constructDelegate (activity );
116+ channel = new MethodChannel (messenger , CHANNEL );
117+ channel .setMethodCallHandler (handler );
118+ observer = new LifeCycleObserver (activity );
119+ if (registrar != null ) {
120+ // V1 embedding setup for activity listeners.
121+ application .registerActivityLifecycleCallbacks (observer );
122+ registrar .addActivityResultListener (delegate );
123+ registrar .addRequestPermissionsResultListener (delegate );
124+ } else {
125+ // V2 embedding setup for activity listeners.
126+ activityBinding .addActivityResultListener (delegate );
127+ activityBinding .addRequestPermissionsResultListener (delegate );
128+ lifecycle = FlutterLifecycleAdapter .getActivityLifecycle (activityBinding );
129+ lifecycle .addObserver (observer );
130+ }
131+ }
132+
133+ ActivityState (final ImagePickerDelegate delegate , final Activity activity ) {
134+ this .activity = activity ;
135+ this .delegate = delegate ;
136+ }
137+
138+ void release () {
139+ if (activityBinding != null ) {
140+ activityBinding .removeActivityResultListener (delegate );
141+ activityBinding .removeRequestPermissionsResultListener (delegate );
142+ activityBinding = null ;
143+ }
144+
145+ if (lifecycle != null ) {
146+ lifecycle .removeObserver (observer );
147+ lifecycle = null ;
148+ }
149+
150+ if (channel != null ) {
151+ channel .setMethodCallHandler (null );
152+ channel = null ;
153+ }
154+
155+ if (application != null ) {
156+ application .unregisterActivityLifecycleCallbacks (observer );
157+ application = null ;
158+ }
159+
160+ activity = null ;
161+ observer = null ;
162+ delegate = null ;
163+ }
164+
165+ Activity getActivity () {
166+ return activity ;
167+ }
168+
169+ ImagePickerDelegate getDelegate () {
170+ return delegate ;
171+ }
172+ }
173+
93174 static final String METHOD_CALL_IMAGE = "pickImage" ;
94175 static final String METHOD_CALL_MULTI_IMAGE = "pickMultiImage" ;
95176 static final String METHOD_CALL_VIDEO = "pickVideo" ;
@@ -101,15 +182,8 @@ public void onActivityStopped(Activity activity) {
101182 private static final int SOURCE_CAMERA = 0 ;
102183 private static final int SOURCE_GALLERY = 1 ;
103184
104- private MethodChannel channel ;
105- private ImagePickerDelegate delegate ;
106185 private FlutterPluginBinding pluginBinding ;
107- private ActivityPluginBinding activityBinding ;
108- private Application application ;
109- private Activity activity ;
110- // This is null when not using v2 embedding;
111- private Lifecycle lifecycle ;
112- private LifeCycleObserver observer ;
186+ private ActivityState activityState ;
113187
114188 @ SuppressWarnings ("deprecation" )
115189 public static void registerWith (io .flutter .plugin .common .PluginRegistry .Registrar registrar ) {
@@ -137,8 +211,12 @@ public ImagePickerPlugin() {}
137211
138212 @ VisibleForTesting
139213 ImagePickerPlugin (final ImagePickerDelegate delegate , final Activity activity ) {
140- this .delegate = delegate ;
141- this .activity = activity ;
214+ activityState = new ActivityState (delegate , activity );
215+ }
216+
217+ @ VisibleForTesting
218+ final ActivityState getActivityState () {
219+ return activityState ;
142220 }
143221
144222 @ Override
@@ -153,13 +231,12 @@ public void onDetachedFromEngine(FlutterPluginBinding binding) {
153231
154232 @ Override
155233 public void onAttachedToActivity (ActivityPluginBinding binding ) {
156- activityBinding = binding ;
157234 setup (
158235 pluginBinding .getBinaryMessenger (),
159236 (Application ) pluginBinding .getApplicationContext (),
160- activityBinding .getActivity (),
237+ binding .getActivity (),
161238 null ,
162- activityBinding );
239+ binding );
163240 }
164241
165242 @ Override
@@ -183,37 +260,15 @@ private void setup(
183260 final Activity activity ,
184261 final PluginRegistry .Registrar registrar ,
185262 final ActivityPluginBinding activityBinding ) {
186- this .activity = activity ;
187- this .application = application ;
188- this .delegate = constructDelegate (activity );
189- channel = new MethodChannel (messenger , CHANNEL );
190- channel .setMethodCallHandler (this );
191- observer = new LifeCycleObserver (activity );
192- if (registrar != null ) {
193- // V1 embedding setup for activity listeners.
194- application .registerActivityLifecycleCallbacks (observer );
195- registrar .addActivityResultListener (delegate );
196- registrar .addRequestPermissionsResultListener (delegate );
197- } else {
198- // V2 embedding setup for activity listeners.
199- activityBinding .addActivityResultListener (delegate );
200- activityBinding .addRequestPermissionsResultListener (delegate );
201- lifecycle = FlutterLifecycleAdapter .getActivityLifecycle (activityBinding );
202- lifecycle .addObserver (observer );
203- }
263+ activityState =
264+ new ActivityState (application , activity , messenger , this , registrar , activityBinding );
204265 }
205266
206267 private void tearDown () {
207- activityBinding .removeActivityResultListener (delegate );
208- activityBinding .removeRequestPermissionsResultListener (delegate );
209- activityBinding = null ;
210- lifecycle .removeObserver (observer );
211- lifecycle = null ;
212- delegate = null ;
213- channel .setMethodCallHandler (null );
214- channel = null ;
215- application .unregisterActivityLifecycleCallbacks (observer );
216- application = null ;
268+ if (activityState != null ) {
269+ activityState .release ();
270+ activityState = null ;
271+ }
217272 }
218273
219274 @ VisibleForTesting
@@ -273,12 +328,13 @@ public void run() {
273328
274329 @ Override
275330 public void onMethodCall (MethodCall call , MethodChannel .Result rawResult ) {
276- if (activity == null ) {
331+ if (activityState == null || activityState . getActivity () == null ) {
277332 rawResult .error ("no_activity" , "image_picker plugin requires a foreground activity." , null );
278333 return ;
279334 }
280335 MethodChannel .Result result = new MethodResultWrapper (rawResult );
281336 int imageSource ;
337+ ImagePickerDelegate delegate = activityState .getDelegate ();
282338 if (call .argument ("cameraDevice" ) != null ) {
283339 CameraDevice device ;
284340 int deviceIntValue = call .argument ("cameraDevice" );
0 commit comments