未验证 提交 983b6e19 编写于 作者: D Dan Field 提交者: GitHub

Call Shell::NotifyLowMemory when backgrounded/memory pressure occurs on Android (#19026)

* Reland "Call Shell::NotifyLowMemoryWarning on Android Trim and LowMemory events (#18979)" (#19023)"

This reverts commit 0a852d8a.
上级 e3fdb233
......@@ -181,4 +181,8 @@ fml::WeakPtr<PlatformViewAndroid> AndroidShellHolder::GetPlatformView() {
return platform_view_;
}
void AndroidShellHolder::NotifyLowMemoryWarning() {
FML_DCHECK(shell_);
shell_->NotifyLowMemoryWarning();
}
} // namespace flutter
......@@ -40,6 +40,8 @@ class AndroidShellHolder {
void UpdateAssetManager(fml::RefPtr<flutter::AssetManager> asset_manager);
void NotifyLowMemoryWarning();
private:
const flutter::Settings settings_;
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
......
......@@ -629,6 +629,9 @@ import java.util.Arrays;
void onTrimMemory(int level) {
ensureAlive();
if (flutterEngine != null) {
// This is always an indication that the Dart VM should collect memory
// and free any unneeded resources.
flutterEngine.getDartExecutor().notifyLowMemoryWarning();
// Use a trim level delivered while the application is running so the
// framework has a chance to react to the notification.
if (level == TRIM_MEMORY_RUNNING_LOW) {
......@@ -651,6 +654,7 @@ import java.util.Arrays;
void onLowMemory() {
Log.v(TAG, "Forwarding onLowMemory() to FlutterEngine.");
ensureAlive();
flutterEngine.getDartExecutor().notifyLowMemoryWarning();
flutterEngine.getSystemChannel().sendMemoryPressureWarning();
}
......
......@@ -845,6 +845,22 @@ public class FlutterJNI {
// TODO(mattcarroll): determine if this is nonull or nullable
private native Bitmap nativeGetBitmap(long nativePlatformViewId);
/**
* Notifies the Dart VM of a low memory event, or that the application is in a state such that now
* is an appropriate time to free resources, such as going to the background.
*
* <p>This is distinct from sending a SystemChannel message about low memory, which only notifies
* the running Flutter application.
*/
@UiThread
public void notifyLowMemoryWarning() {
ensureRunningOnMainThread();
ensureAttachedToNative();
nativeNotifyLowMemoryWarning(nativePlatformViewId);
}
private native void nativeNotifyLowMemoryWarning(long nativePlatformViewId);
private void ensureRunningOnMainThread() {
if (Looper.myLooper() != mainLooper) {
throw new RuntimeException(
......
......@@ -232,6 +232,19 @@ public class DartExecutor implements BinaryMessenger {
}
}
/**
* Notify the Dart VM of a low memory event, or that the application is in a state such that now
* is an appropriate time to free resources, such as going to the background.
*
* <p>This does not notify a Flutter application about memory pressure. For that, use the {@link
* SystemChannel#sendMemoryPressureWarning}.
*/
public void notifyLowMemoryWarning() {
if (flutterJNI.isAttached()) {
flutterJNI.notifyLowMemoryWarning();
}
}
/**
* Configuration options that specify which Dart entrypoint function is executed and where to find
* that entrypoint and other assets required for Dart execution.
......
......@@ -320,6 +320,7 @@ public class FlutterView extends SurfaceView
}
public void onMemoryPressure() {
mNativeView.getFlutterJNI().notifyLowMemoryWarning();
systemChannel.sendMemoryPressureWarning();
}
......
......@@ -438,6 +438,12 @@ static void InvokePlatformMessageEmptyResponseCallback(JNIEnv* env,
);
}
static void NotifyLowMemoryWarning(JNIEnv* env,
jobject obj,
jlong shell_holder) {
ANDROID_SHELL_HOLDER->NotifyLowMemoryWarning();
}
static jboolean FlutterTextUtilsIsEmoji(JNIEnv* env,
jobject obj,
jint codePoint) {
......@@ -508,6 +514,11 @@ bool RegisterApi(JNIEnv* env) {
.fnPtr = reinterpret_cast<void*>(
&InvokePlatformMessageEmptyResponseCallback),
},
{
.name = "nativeNotifyLowMemoryWarning",
.signature = "(J)V",
.fnPtr = reinterpret_cast<void*>(&NotifyLowMemoryWarning),
},
// Start of methods from FlutterView
{
......
package io.flutter.embedding.android;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
import static android.content.ComponentCallbacks2.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Matchers.any;
......@@ -442,7 +442,7 @@ public class FlutterActivityAndFragmentDelegateTest {
}
@Test
public void itSendsMessageOverSystemChannelWhenToldToTrimMemory() {
public void itNotifiesDartExecutorAndSendsMessageOverSystemChannelWhenToldToTrimMemory() {
// Create the real object that we're testing.
FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost);
......@@ -451,14 +451,21 @@ public class FlutterActivityAndFragmentDelegateTest {
delegate.onAttach(RuntimeEnvironment.application);
// Emulate the host and call the method that we expect to be forwarded.
delegate.onTrimMemory(TRIM_MEMORY_RUNNING_MODERATE);
delegate.onTrimMemory(TRIM_MEMORY_RUNNING_LOW);
delegate.onTrimMemory(TRIM_MEMORY_RUNNING_CRITICAL);
delegate.onTrimMemory(TRIM_MEMORY_BACKGROUND);
delegate.onTrimMemory(TRIM_MEMORY_COMPLETE);
delegate.onTrimMemory(TRIM_MEMORY_MODERATE);
delegate.onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
// Verify that the call was forwarded to the engine.
verify(mockFlutterEngine.getDartExecutor(), times(7)).notifyLowMemoryWarning();
verify(mockFlutterEngine.getSystemChannel(), times(1)).sendMemoryPressureWarning();
}
@Test
public void itSendsMessageOverSystemChannelWhenInformedOfLowMemory() {
public void itNotifiesDartExecutorAndSendsMessageOverSystemChannelWhenInformedOfLowMemory() {
// Create the real object that we're testing.
FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost);
......@@ -470,6 +477,7 @@ public class FlutterActivityAndFragmentDelegateTest {
delegate.onLowMemory();
// Verify that the call was forwarded to the engine.
verify(mockFlutterEngine.getDartExecutor(), times(1)).notifyLowMemoryWarning();
verify(mockFlutterEngine.getSystemChannel(), times(1)).sendMemoryPressureWarning();
}
......
......@@ -6,6 +6,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.AssetManager;
import io.flutter.embedding.engine.FlutterJNI;
......@@ -38,4 +39,14 @@ public class DartExecutorTest {
verify(fakeFlutterJni, times(1))
.dispatchPlatformMessage(eq("fake_channel"), eq(fakeMessage), anyInt(), anyInt());
}
@Test
public void itNotifiesLowMemoryWarning() {
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
when(mockFlutterJNI.isAttached()).thenReturn(true);
DartExecutor dartExecutor = new DartExecutor(mockFlutterJNI, mock(AssetManager.class));
dartExecutor.notifyLowMemoryWarning();
verify(mockFlutterJNI, times(1)).notifyLowMemoryWarning();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册