2startup_embedder_framwwork

graph LR
FlutterView-->|对应|DartVM-->|对应|Engine

attachToFlutterEngine图解

分别由FlutterRenderer控制渲染flutter UI到platform侧的FlutterView,由AndroidTouchProcessor控制platform侧的FlutterView的touchEvent到flutter

graph LR
FlutterView-->|attachToFlutterEngine|FlutterEngine
FlutterView-->|interaction events to|FlutterEngine
FlutterEngine-->|renderTo|FlutterView

FlutterEngine-->FlutterRenderer-->|notify|FlutterJNI
RenderSurface-->|nofity surface event|FlutterRenderer

FlutterView-->|contains|RenderSurface

FlutterEngine-->|contains|PlatformViewsController-->|contains|AndroidTouchProcessor-->|sendTouchEvent|Flutter

下述为flutter1.12版本时的源码研究,新版2.0设计上已经进行优化见上面的图解

1.12时在new FlutterView时进行Engine和DartVM的构造和初始化,而在2.0上功能分离到FlutterEngine这个java class中

FlutterApplication.onCreate

/**
 * Flutter implementation of {@link android.app.Application}, managing
 * application-level global initializations.
 */

//FlutterApplication
@CallSuper
 public void onCreate() {
   super.onCreate();
   FlutterMain.startInitialization(this);
 }
  /** FlutterMain
   * Starts initialization of the native system.
   * @param applicationContext The Android application context.
   */
public static void startInitialization(@NonNull Context applicationContext) {
     if (isRunningInRobolectricTest) {
      return;
    }
    FlutterLoader.getInstance().startInitialization(applicationContext);
}

FlutterLoader.startInitialization()

/** Finds Flutter resources in an application APK and also loads Flutter's native library.*/
//FlutterLoader
  
    /**
     * Starts initialization of the native system.
     * @param applicationContext The Android application context.
     */
    public void startInitialization(@NonNull Context applicationContext) {
        startInitialization(applicationContext, new Settings());
    }

    /**Starts initialization of the native system.
     * <p>
     * This loads the Flutter engine's native library to enable subsequent JNI calls. 
This also starts locating and unpacking Dart resources packaged in the app's APK.
     * <p>*/
    public void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) {
     if (Looper.myLooper() != Looper.getMainLooper()) {
          throw new IllegalStateException("startInitialization must be called on the main thread");
        }

        initConfig(applicationContext);
        initResources(applicationContext);

        System.loadLibrary("flutter");//flutter so源码位于engine\shell\platform\android下的BUILD.gn配置

        VsyncWaiter
            .getInstance((WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE))
            .init();

        long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;
        FlutterJNI.nativeRecordStartTimestamp(initTimeMillis);
    }

System.loadLibrary(“flutter”)

//engine/shell/platform/android/library_loader.cc

// This is called by the VM when the shared library is first loaded.
// flutter so的初始化
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  // Initialize the Java VM.
//Android进程在由zygote fork过程中已创建了JavaVM,每一个进程对应一个JavaVM。在这里只是将当前进程的JavaVM实例保存在静态变量,再将当前线程和JavaVM建立关联,获取JNIEnv实例,每个线程对应一个JNIEnv实例
  fml::jni::InitJavaVM(vm);
  JNIEnv* env = fml::jni::AttachCurrentThread();
  bool result = false;

//注册c和java层双向调用的函数信息
  // Register FlutterMain.
  result = flutter::FlutterMain::Register(env);

  // Register PlatformView
  result = flutter::PlatformViewAndroid::Register(env);

  // Register VSyncWaiter.
  result = flutter::VsyncWaiterAndroid::Register(env);

  return JNI_VERSION_1_4;
}
//engine/shell/platform/android/flutter_main.cc
bool FlutterMain::Register(JNIEnv* env) {
  static const JNINativeMethod methods[] = {
      {
          .name = "nativeInit",
          .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/"
                       "lang/String;Ljava/lang/String;Ljava/lang/String;)V",
          .fnPtr = reinterpret_cast<void*>(&Init),
      },
      {
          .name = "nativeRecordStartTimestamp",
          .signature = "(J)V",
          .fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
      },
  };

  jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
  return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
}

VsyncWaiter.init

//VsyncWaiter
    private VsyncWaiter(@NonNull WindowManager windowManager) {
        this.windowManager = windowManager;
    }

    private final FlutterJNI.AsyncWaitForVsyncDelegate asyncWaitForVsyncDelegate = new FlutterJNI.AsyncWaitForVsyncDelegate() {
        @Override
        public void asyncWaitForVsync(long cookie) {
            Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
                @Override
                public void doFrame(long frameTimeNanos) {
                    float fps = windowManager.getDefaultDisplay().getRefreshRate();
                    long refreshPeriodNanos = (long) (1000000000.0 / fps);
                    FlutterJNI.nativeOnVsync(frameTimeNanos, frameTimeNanos + refreshPeriodNanos, cookie);
                }
            });
        }
    };

    public void init() {
        FlutterJNI.setAsyncWaitForVsyncDelegate(asyncWaitForVsyncDelegate);

        // TODO(mattcarroll): look into moving FPS reporting to a plugin
        float fps = windowManager.getDefaultDisplay().getRefreshRate();
        FlutterJNI.setRefreshRateFPS(fps);
    }
//FlutterJNI  
  public static void setAsyncWaitForVsyncDelegate(@Nullable AsyncWaitForVsyncDelegate delegate) {
    asyncWaitForVsyncDelegate = delegate;
  }

  // Called by native.
  private static void asyncWaitForVsync(final long cookie) {
    if (asyncWaitForVsyncDelegate != null) {
      asyncWaitForVsyncDelegate.asyncWaitForVsync(cookie);
    } else {
      throw new IllegalStateException("An AsyncWaitForVsyncDelegate must be registered with FlutterJNI before asyncWaitForVsync() is invoked.");
    }
  }

public static native void nativeOnVsync(long frameTimeNanos, long frameTargetTimeNanos, long cookie);

  public static void setRefreshRateFPS(float refreshRateFPS) {
    FlutterJNI.refreshRateFPS = refreshRateFPS;
  }

public static native void nativeRecordStartTimestamp(long initTimeMillis);

FlutterActivity.onCreate

FlutterActivity extends Activity implements FlutterView.Provider, PluginRegistry, ViewFactory {
  private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);
    // These aliases ensure that the methods we forward to the delegate adhere
    // to relevant interfaces versus just existing in FlutterActivityDelegate.
    private final FlutterActivityEvents eventDelegate = delegate;
    private final FlutterView.Provider viewProvider = delegate;
    private final PluginRegistry pluginRegistry = delegate;
  
   public FlutterActivity() {
   this.eventDelegate = this.delegate;
   this.viewProvider = this.delegate;
   this.pluginRegistry = this.delegate;
 }
  
     /**
     * Returns the Flutter view used by this activity; will be null before
     * {@link #onCreate(Bundle)} is called.
     */
     public FlutterView getFlutterView() { return this.viewProvider.getFlutterView();}
}
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   this.eventDelegate.onCreate(savedInstanceState);
 }
public final class FlutterActivityDelegate
        implements FlutterActivityEvents, FlutterView.Provider,PluginRegistry {
 private FlutterView flutterView;
 private final Activity activity;  
  
  public FlutterActivityDelegate(Activity activity, FlutterActivityDelegate.ViewFactory viewFactory) {
   this.activity = (Activity)Preconditions.checkNotNull(activity);
   this.viewFactory = (FlutterActivityDelegate.ViewFactory)Preconditions.checkNotNull(viewFactory);
 }
  public FlutterView getFlutterView() {    
    return this.flutterView;
  }
    // The implementation of PluginRegistry forwards to flutterView.
    @Override
    public boolean hasPlugin(String key) {
        return flutterView.getPluginRegistry().hasPlugin(key);
    }
    @Override
    public Registrar registrarFor(String pluginKey) {
        return flutterView.getPluginRegistry().registrarFor(pluginKey);
    }
}
public void onCreate(Bundle savedInstanceState) {
 FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args);
 this.flutterView = this.viewFactory.createFlutterView(this.activity);
 if (this.flutterView == null) {
   FlutterNativeView nativeView = this.viewFactory.createFlutterNativeView();
   this.flutterView = new FlutterView(this.activity, (AttributeSet)null, nativeView);
   this.flutterView.setLayoutParams(matchParent);
   this.activity.setContentView(this.flutterView);

 }
    if (loadIntent(activity.getIntent())) {
      return;
    }
    String appBundlePath = FlutterMain.findAppBundlePath();
    if (appBundlePath != null) {
      runBundle(appBundlePath);
    }

FlutterLoader.ensureInitializationComplete

    /** FlutterMain
     * Blocks until initialization of the native system has completed.
     * <p>
     * Calling this method multiple times has no effect.*/
    public static void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {
        if (isRunningInRobolectricTest) {
            return;
        }
        FlutterLoader.getInstance().ensureInitializationComplete(applicationContext, args);
    }
     /** FlutterLoader
     * Blocks until initialization of the native system has completed.
     */
    public void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {
       FlutterJNI.nativeInit(applicationContext, shellArgs.toArray(new String[0]),
                kernelPath, appStoragePath, engineCachesPath);
      
 public static native void nativeInit()

new FlutterView

//FlutterView extends SurfaceView
public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
if (nativeView == null) {
   this.mNativeView = new FlutterNativeView(activity.getApplicationContext());//main
 } else {
   this.mNativeView = nativeView;
 }
  
this.mNativeView.attachViewAndActivity(this, activity);
 this.mSurfaceCallback = new Callback() {
   public void surfaceCreated(SurfaceHolder holder) {
     FlutterView.this.assertAttached();
     FlutterView.this.mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());//main
   }
 
   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
     FlutterView.this.assertAttached();
     FlutterView.this.mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
   }
 
   public void surfaceDestroyed(SurfaceHolder holder) {
     FlutterView.this.assertAttached();
     FlutterView.this.mNativeView.getFlutterJNI().onSurfaceDestroyed();
   }
 };

this.getHolder().addCallback(this.mSurfaceCallback);

this.navigationChannel = new NavigationChannel(this.dartExecutor);
 this.keyEventChannel = new KeyEventChannel(this.dartExecutor);
 this.lifecycleChannel = new LifecycleChannel(this.dartExecutor);
 this.localizationChannel = new LocalizationChannel(this.dartExecutor);
 this.platformChannel = new PlatformChannel(this.dartExecutor);
 this.systemChannel = new SystemChannel(this.dartExecutor);
 this.settingsChannel = new SettingsChannel(this.dartExecutor);
    public FlutterNativeView(@NonNull Context context, boolean isBackgroundView) {
        mContext = context;
        mPluginRegistry = new FlutterPluginRegistry(this, context);
        mFlutterJNI = new FlutterJNI();
        mFlutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
        this.dartExecutor = new DartExecutor(mFlutterJNI, context.getAssets());
        mFlutterJNI.addEngineLifecycleListener(new EngineLifecycleListenerImpl());
        attach(this, isBackgroundView);
        assertAttached();
    }

    private void attach(FlutterNativeView view, boolean isBackgroundView) {
        mFlutterJNI.attachToNative(isBackgroundView);
        dartExecutor.onAttachedToJNI();
    }

attachToNative

  /**
   * Attaches this {@code FlutterJNI} instance to Flutter's native engine, which allows
   * for communication between Android code and Flutter's platform agnostic engine.
   * <p>
   * This method must not be invoked if {@code FlutterJNI} is already attached to native.
   */
  @UiThread
  public void attachToNative(boolean isBackgroundView) {
    ensureRunningOnMainThread();
    ensureNotAttachedToNative();
    nativePlatformViewId = nativeAttach(this, isBackgroundView);
  }

  private void ensureNotAttachedToNative() {
    if (nativePlatformViewId != null) {
      throw new RuntimeException("Cannot execute operation because FlutterJNI is attached to native.");
    }}
}
private native long nativeAttach(@NonNull FlutterJNI flutterJNI, boolean isBackgroundView);
//engine/shell/platform/android/platform_view_android_jni.cc
bool RegisterApi(JNIEnv* env) {
  static const JNINativeMethod flutter_jni_methods[] = {
      // Start of methods from FlutterJNI
      {
          .name = "nativeAttach",
          .signature = "(Lio/flutter/embedding/engine/FlutterJNI;Z)J",
          .fnPtr = reinterpret_cast<void*>(&AttachJNI),
      },
      {
          .name = "nativeRunBundleAndSnapshotFromLibrary",
          .signature = "(JLjava/lang/String;Ljava/lang/String;"
                       "Ljava/lang/String;Landroid/content/res/AssetManager;)V",
          .fnPtr = reinterpret_cast<void*>(&RunBundleAndSnapshotFromLibrary),
      },
  }
  
// Called By Java
static jlong AttachJNI(JNIEnv* env,
                       jclass clazz,
                       jobject flutterJNI,
                       jboolean is_background_view) {
  fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
  auto shell_holder = std::make_unique<AndroidShellHolder>(
      FlutterMain::Get().GetSettings(), java_object, is_background_view);
  if (shell_holder->IsValid()) {
    return reinterpret_cast<jlong>(shell_holder.release());
  } else {
    return 0;
  }
}
AndroidShellHolder::AndroidShellHolder
图解
graph LR
subgraph MessageLoopAndroid是MessageLoopImpl子类
MessageLoopImpl
end

AndroidShellHolder-->|contains|ThreadHost-->|contains|platform_thread
ThreadHost-->|contains|ui_thread
ThreadHost-->|contains|raster_thread
ThreadHost-->|contains|io_tread
ThreadHost-->|contains|profiler_thread
ui_thread-->|contains|TaskRunner-->|contains|MessageLoopImpl

参考messageloop

//engine/shell/platform/android/android_shell_holder

ThreadHost thread_host_;
fml::WeakPtr<PlatformViewAndroid> platform_view_;
std::unique_ptr<Shell> shell_;

AndroidShellHolder::AndroidShellHolder(
    flutter::Settings settings,
    fml::jni::JavaObjectWeakGlobalRef java_object,
    bool is_background_view)
    : settings_(std::move(settings)), java_object_(java_object) {

  if (is_background_view) {
    thread_host_ = {thread_label, ThreadHost::Type::UI};
  } else {
    thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
                                      ThreadHost::Type::IO};//main
  }

  fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
  Shell::CreateCallback<PlatformView> on_create_platform_view = //main
      [is_background_view, java_object, &weak_platform_view](Shell& shell) {
        std::unique_ptr<PlatformViewAndroid> platform_view_android;
          platform_view_android = std::make_unique<PlatformViewAndroid>(
              shell,                   // delegate
              shell.GetTaskRunners(),  // task runners
              java_object,             // java object handle for JNI interop
              shell.GetSettings()
                  .enable_software_rendering  // use software rendering
          );
        weak_platform_view = platform_view_android->GetWeakPtr();
        return platform_view_android;
      };

  Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {//main
    return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
  };

  // The current thread will be used as the platform thread. Ensure that the
  // message loop is initialized.
  fml::MessageLoop::EnsureInitializedForCurrentThread();
  fml::RefPtr<fml::TaskRunner> platform_runner =
      fml::MessageLoop::GetCurrent().GetTaskRunner();
    gpu_runner = thread_host_.gpu_thread->GetTaskRunner();
    ui_runner = thread_host_.ui_thread->GetTaskRunner();
    io_runner = thread_host_.io_thread->GetTaskRunner();

  //main
  flutter::TaskRunners task_runners(thread_label,     // label
                                    platform_runner,  // platform
                                    gpu_runner,       // gpu
                                    ui_runner,        // ui
                                    io_runner         // io
  );

  //main
  shell_ =
      Shell::Create(task_runners,             // task runners
                    GetDefaultWindowData(),   // window data
                    settings_,                // settings
                    on_create_platform_view,  // platform view create callback
                    on_create_rasterizer      // rasterizer create callback
      );
platform_view_ = weak_platform_view;
Shell::Create
class Shell final : public PlatformView::Delegate,
                    public Animator::Delegate,
                    public Engine::Delegate,
                    public Rasterizer::Delegate,
                    public ServiceProtocol::Handler {
  template <class T> using CreateCallback = std::function<std::unique_ptr<T>(Shell&)>;
                      
  std::unique_ptr<Shell> Shell::Create(
    TaskRunners task_runners,
    const WindowData window_data,
    Settings settings,
    Shell::CreateCallback<PlatformView> on_create_platform_view,
    Shell::CreateCallback<Rasterizer> on_create_rasterizer) {

  PerformInitializationTasks(settings);
  PersistentCache::SetCacheSkSL(settings.cache_sksl);

  auto vm = DartVMRef::Create(settings);//main
  FML_CHECK(vm) << "Must be able to initialize the VM.";

  auto vm_data = vm->GetVMData();
  //main
  return Shell::Create(std::move(task_runners),        //
                       std::move(window_data),         //
                       std::move(settings),            //
                       vm_data->GetIsolateSnapshot(),  // isolate snapshot
                       on_create_platform_view,        //
                       on_create_rasterizer,           //
                       std::move(vm)                   //
  );

dart_vm_lifecycle.cc

DartVMRef::Create

DartVMRef DartVMRef::Create(Settings settings,
                            fml::RefPtr<DartSnapshot> vm_snapshot,
                            fml::RefPtr<DartSnapshot> isolate_snapshot) {
  std::scoped_lock lifecycle_lock(gVMMutex);

  // If there is already a running VM in the process, grab a strong reference to it.
  if (auto vm = gVM.lock()) {
    FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was "
                         "already running. Ignoring arguments for current VM "
                         "create call and reusing the old VM.";
    // There was already a running VM in the process,
    return DartVMRef{std::move(vm)};
  }

......

  // If there is no VM in the process. Initialize one, hold the weak reference
  // and pass a strong reference to the caller.
  auto isolate_name_server = std::make_shared<IsolateNameServer>();
  auto vm = DartVM::Create(std::move(settings),          //
                           std::move(vm_snapshot),       //
                           std::move(isolate_snapshot),  //
                           isolate_name_server           //
  );

  gVMData = vm->GetVMData();
  gVMServiceProtocol = vm->GetServiceProtocol();
  gVMIsolateNameServer = isolate_name_server;
  gVM = vm;

  if (settings.leak_vm) {
    gVMLeak = new std::shared_ptr<DartVM>(vm);
  }

  return DartVMRef{std::move(vm)};
std::unique_ptr<Shell> Shell::Create(
    TaskRunners task_runners,
    const WindowData window_data,
    Settings settings,
    fml::RefPtr<const DartSnapshot> isolate_snapshot,
    const Shell::CreateCallback<PlatformView>& on_create_platform_view,
    const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
    DartVMRef vm) {
  PerformInitializationTasks(settings);
  PersistentCache::SetCacheSkSL(settings.cache_sksl);

  fml::AutoResetWaitableEvent latch;
  std::unique_ptr<Shell> shell;
  fml::TaskRunner::RunNowOrPostTask(
      task_runners.GetPlatformTaskRunner(),//main
      fml::MakeCopyable([&latch,                                          //
                         vm = std::move(vm),                              //
                         &shell,                                          //
                         task_runners = std::move(task_runners),          //
                         window_data,                                     //
                         settings,                                        //
                         isolate_snapshot = std::move(isolate_snapshot),  //
                         on_create_platform_view,                         //
                         on_create_rasterizer                             //
  ]() mutable {
        shell = CreateShellOnPlatformThread(std::move(vm),
                                            std::move(task_runners),      //
                                            window_data,                  //
                                            settings,                     //
                                            std::move(isolate_snapshot),  //
                                            on_create_platform_view,      //
                                            on_create_rasterizer          //
        );
        latch.Signal();
      }));
  latch.Wait();
  return shell;
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
    DartVMRef vm,
    TaskRunners task_runners,
    const WindowData window_data,
    Settings settings,
    fml::RefPtr<const DartSnapshot> isolate_snapshot,
    const Shell::CreateCallback<PlatformView>& on_create_platform_view,
    const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {

  auto shell =
      std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));

// Create the rasterizer on the GPU thread.
......

  // Create the platform view on the platform thread (this thread).
  auto platform_view = on_create_platform_view(*shell.get());

  // Ask the platform view for the vsync waiter. This will be used by the engine
  // to create the animator.
  auto vsync_waiter = platform_view->CreateVSyncWaiter();

  // Create the IO manager on the IO thread. The IO manager must be initialized
  // first because it has state that the other subsystems depend on. It must
  // first be booted and the necessary references obtained to initialize the
  // other subsystems.
......

// Create the engine on the UI thread.
  std::promise<std::unique_ptr<Engine>> engine_promise;
  auto engine_future = engine_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
      shell->GetTaskRunners().GetUITaskRunner(),//main
      fml::MakeCopyable([&engine_promise,                                 //
                         shell = shell.get(),                             //
                         &dispatcher_maker,                               //
                         &window_data,                                    //
                         isolate_snapshot = std::move(isolate_snapshot),  //
                         vsync_waiter = std::move(vsync_waiter),          //
                         &weak_io_manager_future,                         //
                         &snapshot_delegate_future,                       //
                         &unref_queue_future                              //
  ]() mutable {
        TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
        const auto& task_runners = shell->GetTaskRunners();

        // The animator is owned by the UI thread but it gets its vsync pulses
        // from the platform.
        auto animator = std::make_unique<Animator>(*shell, task_runners,
                                                   std::move(vsync_waiter));

        engine_promise.set_value(std::make_unique<Engine>(//main
            *shell,                         //
            dispatcher_maker,               //
            *shell->GetDartVM(),            //
            std::move(isolate_snapshot),    //
            task_runners,                   //
            window_data,                    //
            shell->GetSettings(),           //
            std::move(animator),            //
            weak_io_manager_future.get(),   //
            unref_queue_future.get(),       //
            snapshot_delegate_future.get()  //
            ));
      }));

  if (!shell->Setup(std::move(platform_view),  //main
                    engine_future.get(),       //
                    rasterizer_future.get(),   //
                    io_manager_future.get())   //
  ) {
    return nullptr;
  }

  return shell;
Engine::Engine
Engine::Engine(Delegate& delegate,
               const PointerDataDispatcherMaker& dispatcher_maker,
               DartVM& vm,
               fml::RefPtr<const DartSnapshot> isolate_snapshot,
               TaskRunners task_runners,
               const WindowData window_data,
               Settings settings,
               std::unique_ptr<Animator> animator,
               fml::WeakPtr<IOManager> io_manager,
               fml::RefPtr<SkiaUnrefQueue> unref_queue,
               fml::WeakPtr<SnapshotDelegate> snapshot_delegate)
    : delegate_(delegate),
      settings_(std::move(settings)),
      animator_(std::move(animator)),
      activity_running_(true),
      have_surface_(false),
      image_decoder_(task_runners,
                     vm.GetConcurrentWorkerTaskRunner(),
                     io_manager),
      task_runners_(std::move(task_runners)),
      weak_factory_(this) {
  // Runtime controller is initialized here because it takes a reference to this
  // object as its delegate. The delegate may be called in the constructor and
  // we want to be fully initilazed by that point.
  runtime_controller_ = std::make_unique<RuntimeController>(
......

pointer_data_dispatcher_ = dispatcher_maker(*this);
Shell::Shell(DartVMRef vm, TaskRunners task_runners, Settings settings) {
// Install service protocol handlers.
......
  
bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
                  std::unique_ptr<Engine> engine,
                  std::unique_ptr<Rasterizer> rasterizer,
                  std::unique_ptr<ShellIOManager> io_manager) {
  ......
}

activity.setContentView(flutterView)

……

runBundle(appBundlePath)

    private void runBundle(String appBundlePath) {
        if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
            FlutterRunArguments args = new FlutterRunArguments();
            args.bundlePath = appBundlePath;
            args.entrypoint = "main";
            flutterView.runFromBundle(args);//main
        }
    }
    public void runFromBundle(FlutterRunArguments args) {
      assertAttached();
      preRun();
      mNativeView.runFromBundle(args);//main
      postRun();
    }
public void runFromBundle(FlutterRunArguments args) {
        mFlutterJNI.runBundleAndSnapshotFromLibrary(//main
            args.bundlePath,
            args.entrypoint,
            args.libraryPath,
            mContext.getResources().getAssets()
        );

        applicationIsRunning = true;
/** FlutterJNI
   * Executes a Dart entrypoint.
   * <p>
   * This can only be done once per JNI attachment because a Dart isolate can only be
   * entered once.
   */
  @UiThread
  public void runBundleAndSnapshotFromLibrary(
      @NonNull String bundlePath,
      @Nullable String entrypointFunctionName,
      @Nullable String pathToEntrypointFunction,
      @NonNull AssetManager assetManager
  ) {
    ensureRunningOnMainThread();
    ensureAttachedToNative();
    nativeRunBundleAndSnapshotFromLibrary(
        nativePlatformViewId,
        bundlePath,
        entrypointFunctionName,
        pathToEntrypointFunction,
        assetManager
    );
  }
//engine/shell/platform/android/platform_view_android_jni.cc
static void RunBundleAndSnapshotFromLibrary(JNIEnv* env,
                                            jobject jcaller,
                                            jlong shell_holder,
                                            jstring jBundlePath,
                                            jstring jEntrypoint,
                                            jstring jLibraryUrl,
                                            jobject jAssetManager) {
  auto asset_manager = std::make_shared<flutter::AssetManager>();

......
  RunConfiguration config(std::move(isolate_configuration),
                          std::move(asset_manager));

  {
    auto entrypoint = fml::jni::JavaStringToString(env, jEntrypoint);
    auto libraryUrl = fml::jni::JavaStringToString(env, jLibraryUrl);

    if ((entrypoint.size() > 0) && (libraryUrl.size() > 0)) {
      config.SetEntrypointAndLibrary(std::move(entrypoint),
                                     std::move(libraryUrl));
    } else if (entrypoint.size() > 0) {
      config.SetEntrypoint(std::move(entrypoint));
    }
  }

  ANDROID_SHELL_HOLDER->Launch(std::move(config));//main

AndroidShellHolder::Launch

//engine/shell/platform/android/android_shell_holder
void AndroidShellHolder::Launch(RunConfiguration config) {
  if (!IsValid()) {
    return;
  }
  shell_->RunEngine(std::move(config));
}

Shell::RunEngine

void Shell::RunEngine(RunConfiguration run_configuration) {
  RunEngine(std::move(run_configuration), nullptr);
}

void Shell::RunEngine(
    RunConfiguration run_configuration,
    const std::function<void(Engine::RunStatus)>& result_callback) {

......

  fml::TaskRunner::RunNowOrPostTask(
      task_runners_.GetUITaskRunner(),//main
      fml::MakeCopyable(
          [run_configuration = std::move(run_configuration),
           weak_engine = weak_engine_, result]() mutable {
            if (!weak_engine) {
              FML_LOG(ERROR)
                  << "Could not launch engine with configuration - no engine.";
              result(Engine::RunStatus::Failure);
              return;
            }
            auto run_result = weak_engine->Run(std::move(run_configuration));//main
            if (run_result == flutter::Engine::RunStatus::Failure) {
              FML_LOG(ERROR) << "Could not launch engine with configuration.";
            }
            result(run_result);
          }));

Engine::Run

Engine::RunStatus Engine::Run(RunConfiguration configuration) {

  auto isolate_launch_status =
      PrepareAndLaunchIsolate(std::move(configuration));
Engine::RunStatus Engine::PrepareAndLaunchIsolate(
    RunConfiguration configuration) {

  if (configuration.GetEntrypointLibrary().empty()) {
    if (!isolate->Run(configuration.GetEntrypoint(),//main
                      settings_.dart_entrypoint_args)) {
      FML_LOG(ERROR) << "Could not run the isolate.";
      return RunStatus::Failure;
    }
  } 

DartIsolate::Run

bool DartIsolate::Run(const std::string& entrypoint_name,
                      const std::vector<std::string>& args,
                      const fml::closure& on_run) {

  auto user_entrypoint_function =
      Dart_GetField(Dart_RootLibrary(), tonic::ToDart(entrypoint_name.c_str()));

  auto entrypoint_args = tonic::ToDart(args);

  if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {//main
    return false;
  }
  
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function,
                                 Dart_Handle args) {
  Dart_Handle start_main_isolate_function =
      tonic::DartInvokeField(Dart_LookupLibrary(tonic::ToDart("dart:isolate")),
                             "_getStartMainIsolateFunction", {});
  if (tonic::LogIfError(tonic::DartInvokeField(
          Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
          {start_main_isolate_function, user_entrypoint_function, args}))) {//main
    FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
    return false;
  }

  return true;

_runMainZoned

//hooks.dart
@pragma('vm:entry-point')
// ignore: unused_element
void _runMainZoned(Function startMainIsolateFunction,//main
                   Function userMainFunction,//main
                   List<String> args) {
  startMainIsolateFunction((){
    runZoned<void>(() {
      if (userMainFunction is _BinaryFunction) {
        // This seems to be undocumented but supported by the command line VM.
        // Let's do the same in case old entry-points are ported to Flutter.
        (userMainFunction as dynamic)(args, '');
      } else if (userMainFunction is _UnaryFunction) {
        (userMainFunction as dynamic)(args);
      } else {
        userMainFunction();
      }
    }, onError: (Object error, StackTrace stackTrace) {
      _reportUnhandledException(error.toString(), stackTrace.toString());
    });
  }, null);
}