Prototype View recycling for View

Summary:
Prototype of View Recycling for View + generic APIs.

Changelog: [Added][Android] Adding experimental View Recycling for Fabric on Android.

Reviewed By: mdvacca

Differential Revision: D36608419

fbshipit-source-id: c469ce2fe12ef9332d3def591118befc4a619870
This commit is contained in:
Joshua Gross authored and Facebook GitHub Bot committed 2022-05-26 03:40:21 -07:00
1 parent 0ef73f2a82
commit 7b778fbebb
9 files changed
+293 -11

No files matched your search

@@ -7,7 +7,10 @@
package com.facebook.react.uimanager;
import android.content.ComponentCallbacks2;
import android.content.res.Configuration;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.MapBuilder;
import java.util.List;
import java.util.Map;
@@ -20,6 +23,7 @@ public final class ViewManagerRegistry {
private final Map<String, ViewManager> mViewManagers;
private final @Nullable ViewManagerResolver mViewManagerResolver;
private final MemoryTrimCallback mMemoryTrimCallback = new MemoryTrimCallback();
public ViewManagerRegistry(ViewManagerResolver viewManagerResolver) {
mViewManagers = MapBuilder.newHashMap();
@@ -42,6 +46,40 @@ public final class ViewManagerRegistry {
mViewManagerResolver = null;
}
/**
* Trim View Recycling memory aggressively. Whenever the system is running even slightly low on
* memory or is backgrounded, we immediately flush all recyclable Views. GC and memory swaps cause
* intense CPU pressure, so we always favor low memory usage over View recycling, even if there is
* only "moderate" pressure.
*/
private class MemoryTrimCallback implements ComponentCallbacks2 {
@Override
public void onTrimMemory(int level) {
Runnable runnable =
new Runnable() {
@Override
public void run() {
for (Map.Entry<String, ViewManager> entry : mViewManagers.entrySet()) {
entry.getValue().trimMemory();
}
}
};
if (UiThreadUtil.isOnUiThread()) {
runnable.run();
} else {
UiThreadUtil.runOnUiThread(runnable);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {}
@Override
public void onLowMemory() {
this.onTrimMemory(0);
}
}
/**
* @param className {@link String} that identifies the {@link ViewManager} inside the {@link
* ViewManagerRegistry}. This methods {@throws IllegalViewOperationException} if there is no
@@ -91,4 +129,22 @@ public final class ViewManagerRegistry {
}
return null;
}
/** Send lifecycle signal to all ViewManagers that StopSurface has been called. */
public void onSurfaceStopped(int surfaceId) {
Runnable runnable =
new Runnable() {
@Override
public void run() {
for (Map.Entry<String, ViewManager> entry : mViewManagers.entrySet()) {
entry.getValue().onSurfaceStopped(surfaceId);
}
}
};
if (UiThreadUtil.isOnUiThread()) {
runnable.run();
} else {
UiThreadUtil.runOnUiThread(runnable);
}
}
}