mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
parent
d33b91837e
commit
c882439cb3
@ -420,6 +420,7 @@ action("robolectric_tests") {
|
||||
"test/io/flutter/embedding/android/FlutterFragmentTest.java",
|
||||
"test/io/flutter/embedding/android/FlutterViewTest.java",
|
||||
"test/io/flutter/embedding/engine/FlutterEngineCacheTest.java",
|
||||
"test/io/flutter/embedding/engine/FlutterEngineTest.java",
|
||||
"test/io/flutter/embedding/engine/FlutterJNITest.java",
|
||||
"test/io/flutter/embedding/engine/RenderingComponentTest.java",
|
||||
"test/io/flutter/embedding/engine/dart/DartExecutorTest.java",
|
||||
|
||||
@ -8,6 +8,8 @@ import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@ -150,31 +152,35 @@ public class FlutterEngine {
|
||||
* If the Dart VM has already started, the given arguments will have no effect.
|
||||
*/
|
||||
public FlutterEngine(@NonNull Context context, @Nullable String[] dartVmArgs) {
|
||||
this(context, FlutterLoader.getInstance(), new FlutterJNI(), dartVmArgs);
|
||||
this(context, FlutterLoader.getInstance(), new FlutterJNI(), dartVmArgs, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #FlutterEngine(Context, FlutterLoader, FlutterJNI, String[])} but with no Dart
|
||||
* VM flags.
|
||||
* <p>
|
||||
* {@code flutterJNI} should be a new instance that has never been attached to an engine before.
|
||||
*/
|
||||
public FlutterEngine(
|
||||
@NonNull Context context,
|
||||
@NonNull FlutterLoader flutterLoader,
|
||||
@NonNull FlutterJNI flutterJNI
|
||||
) {
|
||||
this(context, flutterLoader, flutterJNI, null);
|
||||
this(context, flutterLoader, flutterJNI, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FlutterEngine}. See {@link #FlutterEngine(Context)}.
|
||||
*
|
||||
* {@code flutterJNI} should be a new instance that has never been attached to an engine before.
|
||||
* Same as {@link #FlutterEngine(Context, FlutterLoader, FlutterJNI)}, plus Dart VM flags in
|
||||
* {@code dartVmArgs}, and control over whether plugins are automatically registered with this
|
||||
* {@code FlutterEngine} in {@code automaticallyRegisterPlugins}. If plugins are automatically
|
||||
* registered, then they are registered during the execution of this constructor.
|
||||
*/
|
||||
public FlutterEngine(
|
||||
@NonNull Context context,
|
||||
@NonNull FlutterLoader flutterLoader,
|
||||
@NonNull FlutterJNI flutterJNI,
|
||||
@Nullable String[] dartVmArgs
|
||||
@Nullable String[] dartVmArgs,
|
||||
boolean automaticallyRegisterPlugins
|
||||
) {
|
||||
this.flutterJNI = flutterJNI;
|
||||
flutterLoader.startInitialization(context);
|
||||
@ -205,6 +211,10 @@ public class FlutterEngine {
|
||||
context.getApplicationContext(),
|
||||
this
|
||||
);
|
||||
|
||||
if (automaticallyRegisterPlugins) {
|
||||
registerPlugins();
|
||||
}
|
||||
}
|
||||
|
||||
private void attachToJni() {
|
||||
@ -222,6 +232,31 @@ public class FlutterEngine {
|
||||
return flutterJNI.isAttached();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all plugins that an app lists in its pubspec.yaml.
|
||||
* <p>
|
||||
* The Flutter tool generates a class called GeneratedPluginRegistrant, which includes the code
|
||||
* necessary to register every plugin in the pubspec.yaml with a given {@code FlutterEngine}.
|
||||
* The GeneratedPluginRegistrant must be generated per app, because each app uses different sets
|
||||
* of plugins. Therefore, the Android embedding cannot place a compile-time dependency on this
|
||||
* generated class. This method uses reflection to attempt to locate the generated file and then
|
||||
* use it at runtime.
|
||||
* <p>
|
||||
* This method fizzles if the GeneratedPluginRegistrant cannot be found or invoked. This situation
|
||||
* should never occur, but if any eventuality comes up that prevents an app from using this
|
||||
* behavior, that app can still write code that explicitly registers plugins.
|
||||
*/
|
||||
private void registerPlugins() {
|
||||
try {
|
||||
Class generatedPluginRegistrant = Class.forName("io.plugins.GeneratedPluginRegistrant");
|
||||
Method registrationMethod = generatedPluginRegistrant.getDeclaredMethod("registerWith", FlutterEngine.class);
|
||||
registrationMethod.invoke(null, this);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Tried to automatically register plugins with FlutterEngine ("
|
||||
+ this + ") but could not find and invoke the GeneratedPluginRegistrant.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up all components within this {@code FlutterEngine} and destroys the associated Dart
|
||||
* Isolate. All state held by the Dart Isolate, such as the Flutter Elements tree, is lost.
|
||||
|
||||
@ -21,6 +21,7 @@ import io.flutter.plugin.common.StandardMessageCodecTest;
|
||||
import io.flutter.plugin.editing.TextInputPluginTest;
|
||||
import io.flutter.plugin.platform.SingleViewPresentationTest;
|
||||
import io.flutter.util.PreconditionsTest;
|
||||
import test.io.flutter.embedding.engine.FlutterEngineTest;
|
||||
import test.io.flutter.embedding.engine.dart.DartExecutorTest;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@ -30,6 +31,7 @@ import test.io.flutter.embedding.engine.dart.DartExecutorTest;
|
||||
FlutterActivityTest.class,
|
||||
FlutterAndroidComponentTest.class,
|
||||
FlutterEngineCacheTest.class,
|
||||
FlutterEngineTest.class,
|
||||
FlutterFragmentTest.class,
|
||||
FlutterJNITest.class,
|
||||
FlutterRendererTest.class,
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package test.io.flutter.embedding.engine;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import io.flutter.embedding.engine.FlutterEngine;
|
||||
import io.flutter.embedding.engine.FlutterJNI;
|
||||
import io.flutter.embedding.engine.loader.FlutterLoader;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Config(manifest=Config.NONE)
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FlutterEngineTest {
|
||||
@Test
|
||||
public void itDoesNotCrashIfGeneratedPluginRegistrantIsUnavailable() {
|
||||
FlutterJNI flutterJNI = mock(FlutterJNI.class);
|
||||
when(flutterJNI.isAttached()).thenReturn(true);
|
||||
|
||||
FlutterEngine flutterEngine = new FlutterEngine(
|
||||
RuntimeEnvironment.application,
|
||||
mock(FlutterLoader.class),
|
||||
flutterJNI,
|
||||
new String[] {},
|
||||
true
|
||||
);
|
||||
// The fact that the above constructor executed without error means that
|
||||
// it dealt with a non-existent GeneratedPluginRegistrant.
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user