preface
Version: Flutter 1.20.4 stable
This series focuses on the process of Android starting up and loading a Flutter project.
This paper mainly analyzes the startInitialization method of FlutterApplication and the whole source code of FlutterActivity
Application
<application android:name="io.flutter.app.FlutterApplication" android:label="flutter_channel" android:icon="@mipmap/ic_launcher"> public class FlutterApplication extends Application { @Override @CallSuper public void onCreate() { super.onCreate(); FlutterMain.startInitialization(this); }}Copy the code
Application is specified as FlutterApplication in the Androidmanifest.xml of the Android project, and is primarily an initialization operation
The startInitialization method in the FlutterLoader class is eventually called
public void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) { if (this.settings ! = null) { return; } if (Looper.myLooper() ! = Looper.getMainLooper()) { throw new IllegalStateException("startInitialization must be called on the main thread"); } applicationContext = applicationContext.getApplicationContext(); this.settings = settings; long initStartTimestampMillis = SystemClock.uptimeMillis(); initConfig(applicationContext); initResources(applicationContext); System.loadLibrary("flutter"); VsyncWaiter.getInstance( (WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE)) .init(); long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis; FlutterJNI.nativeRecordStartTimestamp(initTimeMillis); }Copy the code
- Load the local library of the Flutter engine to enable subsequent JNI calls
- Start locating and opening the Dart resources packaged in the application APK
FlutterApplication does not do too much analysis, just some initialization of resources and some operations of so library loading
FlutterActivity
class MainActivity : FlutterActivity(){}
Copy the code
public class FlutterActivity extends Activity
implements FlutterActivityAndFragmentDelegate.Host, LifecycleOwner {
public FlutterActivity() {
lifecycle = new LifecycleRegistry(this);
}
Copy the code
It is to inherit the Activity and realizes the proxy class FlutterActivityAndFragmentDelegate acquisition life cycle of the Host interface and LifecycleOwner interface
The constructor instantiates a LifecycleRegistry that inherits Lifecycle
public class LifecycleRegistry extends Lifecycle
Copy the code
I then implement the getLifecycle method of the LifecycleOwner interface, which returns the LifecycleRegistry object for listening on and notifying LifecycleOwner status, which I don’t need to go into too much detail
@Override
@NonNull
public Lifecycle getLifecycle() {
return lifecycle;
}
Copy the code
The onCreate method
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
switchLaunchThemeForNormalTheme();
super.onCreate(savedInstanceState);
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
delegate = new FlutterActivityAndFragmentDelegate(this);
delegate.onAttach(this);
delegate.onActivityCreated(savedInstanceState);
configureWindowForTransparency();
setContentView(createFlutterView());
configureStatusBarForFullscreenFlutterExperience();
}
Copy the code
@NonNull
private View createFlutterView() {
return delegate.onCreateView(
null /* inflater */, null /* container */, null /* savedInstanceState */);
}
Copy the code
For the subject and the status bar set, we don’t pay attention to key see configureWindowForTransparency this method and some actions of FlutterActivityAndFragmentDelegate
configureWindowForTransparency
If the FlutterActivity background mode is transparent (default is opaque), make the entire FlutterActivity window transparent and hide the status bar
If we didn’t mix development with FlutterModule in a native project, we wouldn’t have to worry about this approach. Because the default is opaque.
This is just a quick mention, but I’ll cover some configuration of this method when I talk about mixed development
private void configureWindowForTransparency() { BackgroundMode backgroundMode = getBackgroundMode(); if (backgroundMode == BackgroundMode.transparent) { getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); }}Copy the code
FlutterActivityAndFragmentDelegate
- Main is instantiated FlutterActivityAndFragmentDelegate, transfer FlutterActivityAndFragmentDelegate. Host implementation class that is the current class this
- Call the delegate.onAttach, onActivityCreated and onCreateView methods
- About FlutterActivityAndFragmentDelegate introduction, we are on the next article
Other life cycle method is the same, basic it is through LifecycleRegistry. HandleLifecycleEvent set the current interface state. The current life cycle is then delegated to a delegate
@Override
protected void onStart() {
super.onStart();
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START);
delegate.onStart();
}
@Override
protected void onResume() {
super.onResume();
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
delegate.onResume();
}
@Override
public void onPostResume() {
super.onPostResume();
delegate.onPostResume();
}
@Override
protected void onPause() {
super.onPause();
delegate.onPause();
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
Copy the code
Then there is some rewriting FlutterActivityAndFragmentDelegate. The Host interface
/* package */ interface Host
extends SplashScreenProvider, FlutterEngineProvider, FlutterEngineConfigurator {
Copy the code
So let’s take a look at what the methods are for this Host interface
The following is a rough classification according to its use
-
Get Context, Activity, Lifecycle
The method name describe Context getContext(); Getting context objects Activity getActivity(); Get the Activity object Lifecycle getLifecycle(); LifecycleRegistry will be returned when Lifecycle is retrieved -
Instantiation FlutterEngine
The method name describe String getCachedEngineId(); The FlutterEngine Id of the cache FlutterEngine provideFlutterEngine(@NonNull Context context); A FlutterEngine is provided. The current version returns NULL FlutterShellArgs getFlutterShellArgs(); Initialization parameter boolean shouldAttachEngineToActivity(); Establish a connection between the Engine and Activity, and the control interface is used to provide Android resources and lifecycle events to plug-ins attached to the FlutterEngine. PlatformPlugin providePlatformPlugin( @Nullable Activity activity, @NonNull FlutterEngine flutterEngine); Provide a PlatformPlugin (plugin implementation for Android platform) -
Parameters required to run Dart for the first time in FlutterView
The method name describe String getAppBundlePath(); Returns the app Bundle path containing the DART code String getInitialRoute(); Example Initialize a routing path String getDartEntrypointFunctionName(); The DART code executes the entry function name -
Instantiate FlutterSplashView (launch interface and the entire FlutterView)
The method name describe RenderMode getRenderMode(); Flutter UI rendering mode, default is Surface TransparencyMode getTransparencyMode(); Transparency mode, the default is Opaque void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView); FlutterSurfaceView creates the callback void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView); FlutterTextureView creates the callback void onFlutterUiDisplayed(); FlutterView renders the first callback void onFlutterUiNoLongerDisplayed(); FlutterView stops rendering callbacks SplashScreen provideSplashScreen(); Return a SplashScreen The method name describe boolean shouldDestroyEngineWithHost(); Whether to clean engine
Here we only analyze the configureFlutterEngine method implementation in detail, the rest will be explained in the next article
ConfigureFlutterEngine Plug-in registration method
In FlutterActivityAndFragmentDelegate onAttach method call
Void onAttach (@ NonNull Context Context) {/ / omit part of the code host. ConfigureFlutterEngine (flutterEngine); }Copy the code
FlutterActivity implements it as follows
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
registerPlugins(flutterEngine);
}
private static void registerPlugins(@NonNull FlutterEngine flutterEngine) {
try {
Class<?> generatedPluginRegistrant =
Class.forName("io.flutter.plugins.GeneratedPluginRegistrant");
Method registrationMethod =
generatedPluginRegistrant.getDeclaredMethod("registerWith", FlutterEngine.class);
registrationMethod.invoke(null, flutterEngine);
} catch (Exception e) {
Log.w(
TAG,
"Tried to automatically register plugins with FlutterEngine ("
+ flutterEngine
+ ") but could not find and invoke the GeneratedPluginRegistrant.");
}
}
Copy the code
Here by reflecting execution GeneratedPluginRegistrant. RegisterWith method to register the pubspec. Yaml adding plugin dependencies
@Keep public final class GeneratedPluginRegistrant { public static void registerWith(@NonNull FlutterEngine flutterEngine) { flutterEngine.getPlugins().add(new com.befovy.fijkplayer.FijkPlugin()); }}Copy the code
There is no need to manually add flutterengine.getplugins ().add(XXX) to the registerWith method. When pub get is performed, native plug-ins are added to flutter automatically and if we do not register our native plug-ins, This method doesn’t actually need to do anything. The default is automatic registration. This method and its business logic have changed a lot in recent updates to Flutter
If we want to register your own native plugin, you need to rewrite configureFlutterEngine in the MainActivity and call the super. ConfigureFlutterEngine, Then through flutterEngine. Plugins. The add method to register
class MainActivity : FlutterActivity() { override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super. ConfigureFlutterEngine (FlutterEngine) / / primary packaging FlutterPlugin need to manually register flutterEngine.plugins.add(ToastPlugin()) } }Copy the code
conclusion
We can learn from this article
- What does FlutterApplication do
- What does MainActivity inherit from FlutterActivity do
If the above content is inaccurate, please point out in the comments section, I will correct one by one
Next article will analyze FlutterActivityAndFragmentDelegate some logic of the proxy class, this class is the key, It is mainly responsible for some linkage work of FlutterActivity, FlutterEngine, FlutterView, PlatformPlugin, etc. Examples include Engine registration, Dart execution, platform plug-in implementation, and some control over the Activity and Engine life cycles. This article is just a starting point. The core business comes later.