add generic memory pressure listener interface

Reviewed By: lexs

Differential Revision: D2989071

fb-gh-sync-id: 375c7551bd4b281096850732432f016c2684add0
shipit-source-id: 375c7551bd4b281096850732432f016c2684add0
This commit is contained in:
Felix Oghina 2016-03-03 11:11:21 -08:00 committed by Facebook Github Bot 6
parent 9a3f11d3e7
commit c027f05ef4
4 changed files with 40 additions and 15 deletions

View File

@ -2,7 +2,9 @@
package com.facebook.react; package com.facebook.react;
import javax.annotation.Nullable; import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
@ -11,9 +13,8 @@ import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build; import android.os.Build;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.MemoryPressure; import com.facebook.react.bridge.MemoryPressure;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.MemoryPressureListener;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE; import static android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE;
@ -27,7 +28,8 @@ public class MemoryPressureRouter {
// am start -a "com.facebook.catalyst.ACTION_TRIM_MEMORY" --activity-single-top -n <activity> // am start -a "com.facebook.catalyst.ACTION_TRIM_MEMORY" --activity-single-top -n <activity>
private static final String ACTION_TRIM_MEMORY ="com.facebook.catalyst.ACTION_TRIM_MEMORY"; private static final String ACTION_TRIM_MEMORY ="com.facebook.catalyst.ACTION_TRIM_MEMORY";
private @Nullable CatalystInstance mCatalystInstance; private final Set<MemoryPressureListener> mListeners =
Collections.synchronizedSet(new LinkedHashSet<MemoryPressureListener>());
private final ComponentCallbacks2 mCallbacks = new ComponentCallbacks2() { private final ComponentCallbacks2 mCallbacks = new ComponentCallbacks2() {
@Override @Override
public void onTrimMemory(int level) { public void onTrimMemory(int level) {
@ -60,12 +62,18 @@ public class MemoryPressureRouter {
context.getApplicationContext().registerComponentCallbacks(mCallbacks); context.getApplicationContext().registerComponentCallbacks(mCallbacks);
} }
public void onNewReactContextCreated(ReactContext reactContext) { /**
mCatalystInstance = reactContext.getCatalystInstance(); * Add a listener to be notified of memory pressure events.
*/
public void addMemoryPressureListener(MemoryPressureListener listener) {
mListeners.add(listener);
} }
public void onReactInstanceDestroyed() { /**
mCatalystInstance = null; * Remove a listener previously added with {@link #addMemoryPressureListener}.
*/
public void removeMemoryPressureListener(MemoryPressureListener listener) {
mListeners.remove(listener);
} }
public void destroy(Context context) { public void destroy(Context context) {
@ -81,8 +89,12 @@ public class MemoryPressureRouter {
} }
private void dispatchMemoryPressure(MemoryPressure level) { private void dispatchMemoryPressure(MemoryPressure level) {
if (mCatalystInstance != null) { // copy listeners array to avoid ConcurrentModificationException if any of the listeners remove
mCatalystInstance.handleMemoryPressure(level); // themselves in handleMemoryPressure()
MemoryPressureListener[] listeners =
mListeners.toArray(new MemoryPressureListener[mListeners.size()]);
for (MemoryPressureListener listener : listeners) {
listener.handleMemoryPressure(level);
} }
} }

View File

@ -715,7 +715,7 @@ import static com.facebook.react.bridge.ReactMarkerConstants.RUN_JS_BUNDLE_START
catalystInstance.initialize(); catalystInstance.initialize();
mDevSupportManager.onNewReactContextCreated(reactContext); mDevSupportManager.onNewReactContextCreated(reactContext);
mMemoryPressureRouter.onNewReactContextCreated(reactContext); mMemoryPressureRouter.addMemoryPressureListener(catalystInstance);
moveReactContextToCurrentLifecycleState(); moveReactContextToCurrentLifecycleState();
for (ReactRootView rootView : mAttachedRootViews) { for (ReactRootView rootView : mAttachedRootViews) {
@ -772,7 +772,7 @@ import static com.facebook.react.bridge.ReactMarkerConstants.RUN_JS_BUNDLE_START
} }
reactContext.destroy(); reactContext.destroy();
mDevSupportManager.onReactInstanceDestroyed(reactContext); mDevSupportManager.onReactInstanceDestroyed(reactContext);
mMemoryPressureRouter.onReactInstanceDestroyed(); mMemoryPressureRouter.removeMemoryPressureListener(reactContext.getCatalystInstance());
} }
/** /**

View File

@ -21,7 +21,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
* Java APIs be invokable from JavaScript as well. * Java APIs be invokable from JavaScript as well.
*/ */
@DoNotStrip @DoNotStrip
public interface CatalystInstance { public interface CatalystInstance extends MemoryPressureListener {
void runJSBundle(); void runJSBundle();
// This is called from java code, so it won't be stripped anyway, but proguard will rename it, // This is called from java code, so it won't be stripped anyway, but proguard will rename it,
// which this prevents. // which this prevents.
@ -48,8 +48,6 @@ public interface CatalystInstance {
<T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface); <T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface);
Collection<NativeModule> getNativeModules(); Collection<NativeModule> getNativeModules();
void handleMemoryPressure(MemoryPressure level);
/** /**
* Adds a idle listener for this Catalyst instance. The listener will receive notifications * Adds a idle listener for this Catalyst instance. The listener will receive notifications
* whenever the bridge transitions from idle to busy and vice-versa, where the busy state is * whenever the bridge transitions from idle to busy and vice-versa, where the busy state is

View File

@ -0,0 +1,15 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.react.bridge;
/**
* Listener interface for memory pressure events.
*/
public interface MemoryPressureListener {
/**
* Called when the system generates a memory warning.
*/
void handleMemoryPressure(MemoryPressure level);
}