Clear Activity after Being Destroyed

Summary:
[Reported in the support request](https://fb.workplace.com/groups/flippersupport/posts/1237466586733997/), Activity object is held by ObjectTracker even though the Activity is destroyed. This, in this case, caused strict mode in Portal app to forcibly terminate.

This diff tried to remove activities from the reference holder.

Reviewed By: passy

Differential Revision: D31828290

fbshipit-source-id: aad7e8d7ba14069f8dd7c654a3604d482d85e110
This commit is contained in:
Chaiwat Ekkaewnumchai
2021-10-26 03:38:45 -07:00
committed by Facebook GitHub Bot
parent 9ef4303a1a
commit d5e4b0c360
3 changed files with 44 additions and 1 deletions

View File

@@ -27,11 +27,16 @@ public class ApplicationWrapper implements Application.ActivityLifecycleCallback
void onActivityStackChanged(List<Activity> stack); void onActivityStackChanged(List<Activity> stack);
} }
public interface ActivityDestroyedListener {
void onActivityDestroyed(Activity activity);
}
private final Application mApplication; private final Application mApplication;
private final AndroidRootResolver mAndroidRootsResolver; private final AndroidRootResolver mAndroidRootsResolver;
private final List<WeakReference<Activity>> mActivities; private final List<WeakReference<Activity>> mActivities;
private final Handler mHandler; private final Handler mHandler;
private ActivityStackChangedListener mListener; private ActivityStackChangedListener mListener;
private ActivityDestroyedListener mActivityDestroyedListener;
public ApplicationWrapper(Application application) { public ApplicationWrapper(Application application) {
mApplication = application; mApplication = application;
@@ -66,6 +71,10 @@ public class ApplicationWrapper implements Application.ActivityLifecycleCallback
public void onActivityDestroyed(Activity activity) { public void onActivityDestroyed(Activity activity) {
final Iterator<WeakReference<Activity>> activityIterator = mActivities.iterator(); final Iterator<WeakReference<Activity>> activityIterator = mActivities.iterator();
if (mActivityDestroyedListener != null) {
mActivityDestroyedListener.onActivityDestroyed(activity);
}
while (activityIterator.hasNext()) { while (activityIterator.hasNext()) {
if (activityIterator.next().get() == activity) { if (activityIterator.next().get() == activity) {
activityIterator.remove(); activityIterator.remove();
@@ -84,6 +93,10 @@ public class ApplicationWrapper implements Application.ActivityLifecycleCallback
mListener = listener; mListener = listener;
} }
public void setActivityDestroyedListener(ActivityDestroyedListener listener) {
mActivityDestroyedListener = listener;
}
public Application getApplication() { public Application getApplication() {
return mApplication; return mApplication;
} }

View File

@@ -7,8 +7,10 @@
package com.facebook.flipper.plugins.inspector; package com.facebook.flipper.plugins.inspector;
import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
@@ -29,6 +31,7 @@ import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class InspectorFlipperPlugin implements FlipperPlugin { public class InspectorFlipperPlugin implements FlipperPlugin {
private static final String TAG = "ContextDescriptor";
private ApplicationWrapper mApplication; private ApplicationWrapper mApplication;
private DescriptorMapping mDescriptorMapping; private DescriptorMapping mDescriptorMapping;
@@ -91,7 +94,7 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
// Package visible for testing // Package visible for testing
InspectorFlipperPlugin( InspectorFlipperPlugin(
ApplicationWrapper wrapper, ApplicationWrapper wrapper,
DescriptorMapping descriptorMapping, final DescriptorMapping descriptorMapping,
@Nullable List<ExtensionCommand> extensions) { @Nullable List<ExtensionCommand> extensions) {
mDescriptorMapping = descriptorMapping; mDescriptorMapping = descriptorMapping;
@@ -99,6 +102,29 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
mApplication = wrapper; mApplication = wrapper;
mExtensionCommands = extensions; mExtensionCommands = extensions;
mShowLithoAccessibilitySettings = false; mShowLithoAccessibilitySettings = false;
mApplication.setActivityDestroyedListener(
new ApplicationWrapper.ActivityDestroyedListener() {
private final DescriptorMapping mCallbackDescriptorMapping = mDescriptorMapping;
private final ObjectTracker mCallbackObjectTracker = mObjectTracker;
@Override
public void onActivityDestroyed(Activity activity) {
try {
final NodeDescriptor<Activity> activityDescriptor =
(NodeDescriptor<Activity>)
mCallbackDescriptorMapping.descriptorForClass(Activity.class);
if (activityDescriptor == null || mCallbackObjectTracker == null) {
return;
}
String activityId = activityDescriptor.getId(activity);
mCallbackObjectTracker.remove(activityId);
} catch (Exception e) {
// Ignore if there is an error
Log.d(TAG, "Cannot remove activity from ObjectTracker: " + e.getMessage());
}
}
});
} }
@Override @Override

View File

@@ -40,6 +40,10 @@ public class ObjectTracker {
mObjects.clear(); mObjects.clear();
} }
public void remove(String id) {
mObjects.remove(id);
}
public boolean contains(String id) { public boolean contains(String id) {
return mObjects.containsKey(id); return mObjects.containsKey(id);
} }