Flutter是怎麼啓動起來的,是在Android的Activity的啓動以後嗎?等等這樣的問題,在這個文章中將被解答。java
新建立一個Flutter項目,在清單文件中默認被啓動的Activity是MainActivity,而MainActivity繼承的是FlutterActivity。那麼問題好像簡單了,咱們分析一下FlutterActivity,下面是MainActivity的代碼。shell
public class MainActivity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); } } 複製代碼
上面的源碼很簡單,有兩個點須要關注,第一個就是在MainActivity.onCreate()中調用了GeneratedPluginRegistrant.registerWith()這個方法,第二個是MainActivity繼承自FlutterActivity,咱們對這兩個關注點依次進行分析。json
咱們查看GeneratedPluginRegistrant,發現這個類是Android Studio自動生成的,而且不建議修改,這個類也很是簡單,下面是GeneratedPluginRegistrant的代碼。bash
public final class GeneratedPluginRegistrant { public static void registerWith(PluginRegistry registry) { if (alreadyRegisteredWith(registry)) { return; } } private static boolean alreadyRegisteredWith(PluginRegistry registry) { final String key = GeneratedPluginRegistrant.class.getCanonicalName(); if (registry.hasPlugin(key)) { return true; } registry.registrarFor(key); return false; } } 複製代碼
若是PluginRegistry已經包含了GeneratedPluginRegistrant就直接返回true,如沒有就調用PluginRegistry.registrarFor()進行註冊。markdown
咱們分析一下PluginRegistry,看看是怎麼註冊的,發現PluginRegistry是一個接口,下面是PluginRegistry的代碼。app
public interface PluginRegistry { Registrar registrarFor(String pluginKey); } 複製代碼
PluginRegistry的實現是誰呢?是FlutterActivity,下面開發分析FlutterActivity,暫時看FlutterActivity比較重要,由於這個類是MainActivity的父類,仍是PluginRegistry的具體實現類。ide
下面是FlutterActivity的代碼。oop
public class FlutterActivity extends Activity implements FlutterView.Provider, PluginRegistry, ViewFactory { private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this); private final FlutterActivityEvents eventDelegate = delegate; private final FlutterView.Provider viewProvider = delegate; private final PluginRegistry pluginRegistry = delegate; @Override public final boolean hasPlugin(String key) { return pluginRegistry.hasPlugin(key); } @Override public final Registrar registrarFor(String pluginKey) { return pluginRegistry.registrarFor(pluginKey); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); eventDelegate.onCreate(savedInstanceState); } @Override protected void onDestroy() { eventDelegate.onDestroy(); super.onDestroy(); } @Override protected void onStop() { eventDelegate.onStop(); super.onStop(); } //省略了一些代碼 } 複製代碼
從上面的代碼中能夠看出來,FlutterActivity是繼承Activity和實現了PluginRegistry。分析一下onCreate,onStop,onDestroy這些生命週期方法被FlutterActivity.eventDelegate代理了,這個時候咱們明白了,FlutterActivity就是一個空殼,真正實現是代理類FlutterActivityDelegate。this
咱們具體看一下,下面是FlutterActivity.onCreate()的代碼。spa
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); eventDelegate.onCreate(savedInstanceState); } 複製代碼
FlutterActivity.$onCreate()比較簡單,調用了super的onCreate()和eventDelegate.onCreate(),也就是調用了代理類的onCreate方法,下面分析FlutterActivityDelegate。
從上面的分析能夠得出結論,FlutterActivity什麼都沒有作,都交個了FlutterActivityDelegate去幹,這裏類實現了PluginRegistry,下面是FlutterActivityDelegate的代碼。
public final class FlutterActivityDelegate implements FlutterActivityEvents, FlutterView.Provider, PluginRegistry { @Override public void onCreate(Bundle savedInstanceState) { } } 複製代碼
仍是先分析FlutterActivityDelegate.onCreate(),這個真正幹活的onCreate方法仍是比較複雜的,下面是FlutterActivityDelegate.onCreate()的代碼。
@Override public void onCreate(Bundle savedInstanceState) { String[] args = getArgsFromIntent(activity.getIntent());//1 FlutterMain.ensureInitializationComplete(activity.getApplicationContext(), args);//2 flutterView = viewFactory.createFlutterView(activity);//3 if (flutterView == null) { FlutterNativeView nativeView = viewFactory.createFlutterNativeView(); flutterView = new FlutterView(activity, null, nativeView);//4 flutterView.setLayoutParams(matchParent); activity.setContentView(flutterView);//5 launchView = createLaunchView(); if (launchView != null) { addLaunchView(); } } if (loadIntent(activity.getIntent())) { return; } String appBundlePath = FlutterMain.findAppBundlePath(activity.getApplicationContext()); if (appBundlePath != null) { runBundle(appBundlePath); } } 複製代碼
獲得了一些參數,這些參數是幹啥用的?咱們拿一個trace-startup參數爲例進行簡單介紹下面是FlutterActivityDelegate.getArgsFromIntent()的代碼。
private static String[] getArgsFromIntent(Intent intent) { ArrayList<String> args = new ArrayList<>(); if (intent.getBooleanExtra("trace-startup", false)) { args.add("--trace-startup"); } if (intent.getBooleanExtra("start-paused", false)) { args.add("--start-paused"); } if (!args.isEmpty()) { String[] argsArray = new String[args.size()]; return args.toArray(argsArray); } return null; } 複製代碼
當你安裝一個App的時候,能夠用下面這個命令,
flutter run --trace-startup --profile
複製代碼
安裝完以後會生下面這個json,
{ "engineEnterTimestampMicros": 273508186457, "timeToFrameworkInitMicros": 271420, "timeToFirstFrameMicros": 469796, "timeAfterFrameworkInitMicros": 198376 } 複製代碼
這個json會顯示進入Flutter引擎的時間和展現應用第一幀的時間等等。
調用 FlutterMain.ensureInitializationComplete(),這方法初始化了Flutter,下面是ensureInitializationComplete的代碼。
public static void ensureInitializationComplete(Context applicationContext, String[] args) { if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("ensureInitializationComplete must be called on the main thread"); } try { sResourceExtractor.waitForCompletion(); List<String> shellArgs = new ArrayList<>(); shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat"); String appBundlePath = findAppBundlePath(applicationContext); String appStoragePath = PathUtils.getFilesDir(applicationContext); nativeInit(applicationContext, shellArgs.toArray(new String[0]), appBundlePath, appStoragePath, engineCachesPath);//1 } catch (Exception e) { Log.e(TAG, "Flutter initialization failed.", e); throw new RuntimeException(e); } } //native方法 private static native void nativeInit(Context context, String[] args, String bundlePath, String appStoragePath, String engineCachesPath); 複製代碼
先判斷是否是主線程,若是不是主線程直接拋出異常。初始化參數調用 FlutterMain.nativeInit()方法,這個方法是native方法,主要的用途是初始化Flutter。
ViewFactory是一個接口,ViewFactory.createFlutterView()的具體實現有兩個,分別是FlutterActivity.createFlutterView()和FlutterFragmentActivity.createFlutterView()如今這個兩個具體實現都返回null,也就是必定會走到註釋4。
建立FlutterView,那麼FlutterView是什麼呢?看一下類的聲明,下面是FlutterView的聲明的代碼,
public class FlutterView extends SurfaceView implements BinaryMessenger, TextureRegistry } 複製代碼
原來是一 SurfaceView,這個就很容易理解了。
關鍵來了,下面是調用setContentView的代碼,
activity.setContentView(flutterView);
複製代碼
把FlutterView加載到Activity中,折騰了半天,就是作了這樣一件事,說白了就是建立了一個FlutterView,而且把這個view顯示到屏幕上。
下面是Flutter的啓動流程圖。