Flutter Engine源码粗看

io.flutter.embedding.android.FlutterActivity(如无特殊说明,下文中的FlutterActivity单指此包下的类。)重写了android.app.Activity中的onCreate方法:

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
      //...
      setContentView(createFlutterView());
      //...
  }

再来看一下方法createFlutterView()的源码:

 @NonNull
  private View createFlutterView() {
    return delegate.onCreateView(null,null,null,FLUTTER_VIEW_ID,getRenderMode() == RenderMode.surface);
  }

可以看到,这里调用了一个delegate的onCreateView(…)方法。这个变量delegate是什么东西?在哪里被设值了?可以变更吗?它是FlutterActivity中的一个变量:

protected FlutterActivityAndFragmentDelegate delegate;

它在onCreate方法中被初始化了:

 @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    //...
    delegate = new FlutterActivityAndFragmentDelegate(this);
    //...
    setContentView(createFlutterView());
    //...
  }

接着看一下这个delegate的onCreateView(…)方法的源码:

@NonNull
  View onCreateView(
      LayoutInflater inflater,
      @Nullable ViewGroup container,
      @Nullable Bundle savedInstanceState,
      int flutterViewId,
      boolean shouldDelayFirstAndroidViewDraw) {
    //...
    flutterView.attachToFlutterEngine(flutterEngine);
    //...
  }

大致意思就是把flutterView attach到FlutterEngine(Flutter引擎)上去,并且提供了一个引擎对象flutterEngine。FlutterEngine是什么?简单地说,它使得在Android Application中执行Dart成为可能。再简单点说,它就是一个黑盒子,里面在执行Dart代码。至于它到底还干了什么别的,具体怎么干的?我也不知道。
接下来找找看这个引擎对象是如何被初始化的。

class FlutterActivityAndFragmentDelegate implements ... {
    @Nullable private FlutterEngine flutterEngine;

    void setupFlutterEngine() {
        //...
        // First, check if the host wants to use a cached FlutterEngine.
        //...
        // Second, defer to subclasses for a custom FlutterEngine.
        //...
        // Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our
        // FlutterView.
        //...
  }
}

源码注释的大致意思应该是:第一步,缓存的引擎用不用?用就返回。第二步,子类有没有提供自己的引擎?有就返回。第三步,创建一个,并返回。这里暂且不管它的引擎缓存机制是如何实现的,也不管它的子类提供引擎的机制是什么,先看一下它是如何被创建出来的。

void setupFlutterEngine() {
    //...
    flutterEngine = new FlutterEngine(
            host.getContext(),
            host.getFlutterShellArgs().toArray(),
            false,
            host.shouldRestoreAndSaveState());
    //...
  }

只是调了一个构造而已嘛!没什么大不了的。当我们仔细地观察会发现,所有构造器最后都指向同一个构造器,即

public FlutterEngine(
      @NonNull Context context,
      @Nullable FlutterLoader flutterLoader,
      @NonNull FlutterJNI flutterJNI,
      @NonNull PlatformViewsController platformViewsController,
      @Nullable String[] dartVmArgs,
      boolean automaticallyRegisterPlugins,
      boolean waitForRestorationData)

此处,我们暂且不关注该构造器的具体实现,只看该方法的最后几行代码,如下所示:

//...
if (automaticallyRegisterPlugins && flutterLoader.automaticallyRegisterPlugins()) {
      GeneratedPluginRegister.registerGeneratedPlugins(this);
    }
public static void registerGeneratedPlugins(@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.e(
          TAG,
          "Tried to automatically register plugins with FlutterEngine ("
              + flutterEngine
              + ") but could not find or invoke the GeneratedPluginRegistrant.");
      Log.e(TAG, "Received exception while registering", e);
    }
  }

这是一段极为普通的反射代码,它执行了类io.flutter.plugins.GeneratedPluginRegistrant的方法registerWith,是不是非常眼熟了?在我们的Flutter APP中android文件夹下就有一个自动生成的类与之同名,即

public final class GeneratedPluginRegistrant {
  private static final String TAG = "GeneratedPluginRegistrant";
  public static void registerWith(@NonNull FlutterEngine flutterEngine) {
    //...
  }
}

现在我们知道了,当引擎被构造时,就会去注册插件。那么除了这一时机之外,还会有其它时机注册插件吗?
FlutterActivity类有代码如下所示:

@Override
  public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
    //...
    GeneratedPluginRegister.registerGeneratedPlugins(flutterEngine);
  }

@Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    //...
    delegate = new FlutterActivityAndFragmentDelegate(this);
    delegate.onAttach(this);
    //...
    setContentView(createFlutterView());
    //...
  }

FlutterFragmentActivity类有代码如下所示:

@Override
  public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
    //...
    GeneratedPluginRegister.registerGeneratedPlugins(flutterEngine);
  }

FlutterActivityAndFragmentDelegate类有代码如下所示:

void onAttach(@NonNull Context context) {
    //...
    if (flutterEngine == null) {
      setupFlutterEngine();
    }
    //...
    host.configureFlutterEngine(flutterEngine);
    isAttached = true;
  }

FlutterFragment类有代码如下所示:

@Override
  public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
    FragmentActivity attachedActivity = getActivity();
    if (attachedActivity instanceof FlutterEngineConfigurator) {
      ((FlutterEngineConfigurator) attachedActivity).configureFlutterEngine(flutterEngine);
    }
  }

@Override
  public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    delegate = new FlutterActivityAndFragmentDelegate(this);
    delegate.onAttach(context);
    //...
  }

综上,上面的问题也就迎刃而解了。
接下来先看一下引擎这个类的大致格局:

public class FlutterEngine {
  //...
  @NonNull private final FlutterJNI flutterJNI;
  @NonNull private final FlutterRenderer renderer;
  @NonNull private final DartExecutor dartExecutor;
  @NonNull private final FlutterEngineConnectionRegistry pluginRegistry;
  @NonNull private final LocalizationPlugin localizationPlugin;

  // System channels.
  @NonNull private final AccessibilityChannel accessibilityChannel;
  @NonNull private final DeferredComponentChannel deferredComponentChannel;
  @NonNull private final KeyEventChannel keyEventChannel;
  @NonNull private final LifecycleChannel lifecycleChannel;
  @NonNull private final LocalizationChannel localizationChannel;
  @NonNull private final MouseCursorChannel mouseCursorChannel;
  @NonNull private final NavigationChannel navigationChannel;
  @NonNull private final RestorationChannel restorationChannel;
  @NonNull private final PlatformChannel platformChannel;
  @NonNull private final SettingsChannel settingsChannel;
  @NonNull private final SystemChannel systemChannel;
  @NonNull private final TextInputChannel textInputChannel;

  // Platform Views.
  @NonNull private final PlatformViewsController platformViewsController;

  // Engine Lifecycle.
  @NonNull private final Set<EngineLifecycleListener> engineLifecycleListeners = new HashSet<>();

  @NonNull
  private final EngineLifecycleListener engineLifecycleListener =...;
//...
}

所有域都是非空final的,这给源码阅读带来好处,因为设值的地方肯定只有一处。此类除了这些域之外,还有各种构造、各种通道、插件注册和引擎生命周期相关的方法。
先看引擎生命周期。

public void addEngineLifecycleListener(@NonNull EngineLifecycleListener listener){//...}

public void removeEngineLifecycleListener(@NonNull EngineLifecycleListener listener){//...}

public interface EngineLifecycleListener {
    void onPreEngineRestart();
    void onEngineWillDestroy();
  }

可以看到引擎提供了一个引擎生命周期监听器接口、两个方法,分别是添加、删除引擎生命周期监听器。源码看到此处,免不得要实践一下,试试这个接口中的两个方法是否会回调。

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final FlutterEngine fe = getFlutterEngine();
        if (fe != null) {
            fe.addEngineLifecycleListener(new FlutterEngine.EngineLifecycleListener() {
                @Override
                public void onPreEngineRestart() {
                    Log.d("Harry", "onPreEngineRestart");
                }

                @Override
                public void onEngineWillDestroy() {
                    Log.d("Harry", "onEngineWillDestroy");
                }
            });
        }
    }

在FlutterActivity的子类MainActivity中重写onCreate方法,然后添加一个监听器即可。然后在命令行中使用flutter run启动Flutter应用程序,待应用程序启动完毕后,在终端输入大写的R,即Hot restart,然后按返回键退出应用程序,在日志中便可以看到日志如下所示:

2022-04-23 18:35:12.578 ... D/Harry: onPreEngineRestart
2022-04-23 18:45:10.733 ... D/Harry: onEngineWillDestroy

在FlutterEngine类中,第一个非空final域就是变量flutterJNI,那么就进去走马观花一下。进去一看,才发现这个类1000多行代码,这得看到猴年马月去!算了,不看了,不看了。
既来之,则安之。随便看看何妨?又不是进来寻找武林至尊秘籍的,看着不爽咱就撤。
闲言少叙,开始走马观花。

public void loadLibrary() {
    //...
    System.loadLibrary("flutter");
    //...
  }

这段代码应该很熟悉哦?就是加载libflutter.so库。

private static native void nativeInit(
      @NonNull Context context,
      @NonNull String[] args,
      @Nullable String bundlePath,
      @NonNull String appStoragePath,
      @NonNull String engineCachesPath,
      long initTimeMillis);

public void init(
      @NonNull Context context,
      @NonNull String[] args,
      @Nullable String bundlePath,
      @NonNull String appStoragePath,
      @NonNull String engineCachesPath,
      long initTimeMillis) {
    //...
    FlutterJNI.nativeInit(context, args, bundlePath, appStoragePath, engineCachesPath, initTimeMillis);
    //...
  }

看样子,这里就是初始化FlutterJNI的地方了,只是它调用了一个native方法,换言之,真正初始化的代码在底层,是用C/C++完成的。咦!这好像一个小黑洞,洞外山丘高耸、丛林密布,站在洞外往里看,深不可测,甚是神秘。它太吸引人了,咱不妨动动手指往里探探?你能忍住不这么做?
shell/platform/android目录下,有个flutter_main.h头文件。

//...
class FlutterMain {
 public:
  //...
 private:
  //...
  static void Init(JNIEnv* env,
                   jclass clazz,
                   jobject context,
                   jobjectArray jargs,
                   jstring kernelPath,
                   jstring appStoragePath,
                   jstring engineCachesPath,
                   jlong initTimeMillis);
    //..
};

看来是用C++写的。此处的static void Init(...)函数和前面提到的private static native void nativeInit(...)方法的参数是不是甚为相似?在Init(...)函数形参中,前两个参数envclazz分别代表jni执行环境(参看Java与C/C++交互相关内容)和FlutterJNI类对象(因为nativeInit(...)方法是用static修饰的)。这里是头文件,只是声明了该函数的签名,该函数的具体实现还得看源文件,接下来打开flutter_main.cc源文件,这个文件篇幅还可以,200多行代码。
咱先找找看,是什么把上面提到的一个函数和一个方法进行关联起来的。

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;J)V",
          .fnPtr = reinterpret_cast<void*>(&Init),
      },
      //...
  };

  jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
  //...
}

这段代码可以证明上面所说的是正确的。况且这段代码不难理解:方法有名字、签名、函数指针,分别对应代码中的name、signature、fnPtr,其中函数指针就是上面头文件里声明的Init(...)函数,至于reinterpret_cast<void*>(&Init)到底啥意思也不必深究,说白了就是强制转换,然后用jni找到FlutterJNI类对象。咱知道这些就够了,毕竟是走马观花嘛!哦对了,咱的马还栓在洞外呢!这个洞里是不是很爽?冬暖夏凉。哎呀!哪里来的水流淋在咱头上了?
好,回到正题上,再探探FlutterJNI底层初始化是怎么做的?

void FlutterMain::Init(JNIEnv* env,
                       jclass clazz,
                       jobject context,
                       jobjectArray jargs,
                       jstring kernelPath,
                       jstring appStoragePath,
                       jstring engineCachesPath,
                       jlong initTimeMillis) {
  std::vector<std::string> args;
  args.push_back("flutter");
  for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
    args.push_back(std::move(arg));
  }
  auto command_line = fml::CommandLineFromIterators(args.begin(), args.end());

  auto settings = SettingsFromCommandLine(command_line);
  //...
  g_flutter_main.reset(new FlutterMain(std::move(settings)));
  //...
}

大致意思就是,定义一个向量,相当于数组,然后往里塞字符串"flutter",再往里塞其它必要的参数,之后生成命令行,根据命令行生成settings,最后构造一个FlutterMain的对象。知道了这些,好像没啥用哦。
你挑上担,他牵上马,我继续观花。

@Nullable private PlatformMessageHandler platformMessageHandler;

刚走不久,这个变量引起了我的注意,表面意思是平台消息Handler,干嘛用的呢?先猜猜看,这里所说的platform可能是跨平台的平台,相当于Android、iOS等。猜错了也没关系嘛。既然是平台消息,那多多少少跟Flutter与这些平台之间的消息交互挂点钩。

/** Handler that receives messages from Dart code. */
public interface PlatformMessageHandler {
  void handleMessageFromDart(
      @NonNull final String channel,
      @Nullable ByteBuffer message,
      final int replyId,
      long messageData);

  void handlePlatformMessageResponse(int replyId, @Nullable ByteBuffer reply);
}

没打开这个类之前,原以为这个类会相当庞大,没想到就这么几行而已。这个类的注释写着:这是一个Handler,用来接收从Dart那儿发过来的消息。Dart发给谁的消息要它接收呀?引擎本身,还是Android?既然Dart会有消息发过来,那么这边肯定可以发消息给Dart。既然如此,那又是怎么做到的呢?咱继续看。

private native void nativeDispatchEmptyPlatformMessage(
      long nativeShellHolderId, @NonNull String channel, int responseId);

这是FlutterJNI对象可以调用的本地方法,用来发送一条空平台消息给Dart。不出意料,又是C/C++底层实现的。咱去找找看,到底是如何实现的。
shell/platform/android目录下,有个platform_view_android_jni_impl.cc源文件。

{
.name = "nativeDispatchEmptyPlatformMessage",
.signature = "(JLjava/lang/String;I)V",
.fnPtr = reinterpret_cast<void*>(&DispatchEmptyPlatformMessage),
}

顺藤摸瓜。

void PlatformViewAndroid::DispatchEmptyPlatformMessage(JNIEnv* env,
                                                       std::string name,
                                                       jint response_id) {
  fml::RefPtr<flutter::PlatformMessageResponse> response;
  if (response_id) {
    response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
        response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
  }

  PlatformView::DispatchPlatformMessage(
      std::make_unique<flutter::PlatformMessage>(std::move(name),
                                                 std::move(response)));
}

这是分发空平台消息的底层实现,什么意思呢?如果response_id非0,就给response指针赋一个值,连带name,交付给PlatformView::DispatchPlatformMessage(...)的。那么此函数又是如何实现的呢?

void PlatformView::DispatchPlatformMessage(
    std::unique_ptr<PlatformMessage> message) {
  delegate_.OnPlatformViewDispatchPlatformMessage(std::move(message));
}

不禁要问,这里的delegate_是什么,这个函数又做了什么?这里将它理解为一个平台视图的委托即可。

void Shell::OnPlatformViewDispatchPlatformMessage(
    std::unique_ptr<PlatformMessage> message) {
  //...
  task_runners_.GetUITaskRunner()->PostTask(fml::MakeCopyable(
      [engine = engine_->GetWeakPtr(), message = std::move(message)]() mutable {
        if (engine) {
          engine->DispatchPlatformMessage(std::move(message));
        }
      }));
}

原来是往任务队列里塞了一个任务,而这个任务就是发送消息。那么上面代码中的engine->DispatchPlatformMessage(std::move(message));又做了件什么事情呢?

void Engine::DispatchPlatformMessage(std::unique_ptr<PlatformMessage> message) {
  std::string channel = message->channel();
  if (channel == kLifecycleChannel) {
    if (HandleLifecyclePlatformMessage(message.get())) {
      return;
    }
  } else if (channel == kLocalizationChannel) {
    if (HandleLocalizationPlatformMessage(message.get())) {
      return;
    }
  } else if (channel == kSettingsChannel) {
    HandleSettingsPlatformMessage(message.get());
    return;
  } else if (!runtime_controller_->IsRootIsolateRunning() &&
             channel == kNavigationChannel) {
    // If there's no runtime_, we may still need to set the initial route.
    HandleNavigationPlatformMessage(std::move(message));
    return;
  }

  if (runtime_controller_->IsRootIsolateRunning() &&
      runtime_controller_->DispatchPlatformMessage(std::move(message))) {
    return;
  }

  FML_DLOG(WARNING) << "Dropping platform message on channel: " << channel;
}

然后就是根据不同的通道进行消息分发。这里咱不看其它通道消息是如何分发的,单看最后一个运行时控制器是如何分发消息的。

bool RuntimeController::DispatchPlatformMessage(
    std::unique_ptr<PlatformMessage> message) {
    //...
    platform_configuration->DispatchPlatformMessage(std::move(message));
    //...
}

怎么调用还没完!我都快没耐心了!

void PlatformConfiguration::DispatchPlatformMessage(
    std::unique_ptr<PlatformMessage> message) {
  //...
  tonic::CheckAndHandleError(
      tonic::DartInvoke(dispatch_platform_message_.Get(),
                        {tonic::ToDart(message->channel()), data_handle,
                         tonic::ToDart(response_id)}));
}

好像有门儿!。

Dart_Handle DartInvoke(Dart_Handle closure,
                       std::initializer_list<Dart_Handle> args) {
  int argc = args.size();
  Dart_Handle* argv = const_cast<Dart_Handle*>(args.begin());
  Dart_Handle handle = Dart_InvokeClosure(closure, argc, argv);
  CheckAndHandleError(handle);
  return handle;
}

函数参数是一个闭包和一个列表,实现是把列表大小给argc,argv指向列表头,然后传入参数执行闭包。这里的闭包实参应该就是上面的dispatch_platform_message_.Get(),列表实参应该就是上面的
{tonic::ToDart(message->channel()), data_handle,tonic::ToDart(response_id)}

在FlutterEngine类中,第二个非空final域就是变量renderer,那么就进去走马观花一下。顾名思义,它是一个渲染器,用来在Android视图层次结构中把Flutter页面绘制出来。那么绘制在哪里呢?这不废话嘛!前一句不是刚说完嘛!这里说的是更直接的地方,它是一个Surface,是由RenderSurface提供的。那RenderSurface又是什么呢?

public interface RenderSurface {
  @Nullable
  FlutterRenderer getAttachedRenderer();
  void attachToRenderer(@NonNull FlutterRenderer renderer);
  void detachFromRenderer();
  void pause();
}

以上便是它的所有代码了,可是它是如何提供Surface的呢?它只是一个接口,那么要从它的实现者入手了。

public class FlutterImageView extends View implements RenderSurface
public class FlutterSurfaceView extends SurfaceView implements RenderSurface
public class FlutterTextureView extends TextureView implements RenderSurface

从源码可以清晰地发现,它的实现者有三个,分别是:FlutterImageViewFlutterSurfaceViewFlutterTextureView。好了,到目前为止,已经知道了真正提供Surface的是谁了,至于它们仨又是如何实现的,此处不作赘述。

@NonNull private final FlutterJNI flutterJNI;
  //...
  private boolean isDisplayingFlutterUi = false;

private final FlutterUiDisplayListener flutterUiDisplayListener =
      new FlutterUiDisplayListener() {
        @Override
        public void onFlutterUiDisplayed() {
          isDisplayingFlutterUi = true;
        }

        @Override
        public void onFlutterUiNoLongerDisplayed() {
          isDisplayingFlutterUi = false;
        }
      };

public FlutterRenderer(@NonNull FlutterJNI flutterJNI) {
    this.flutterJNI = flutterJNI;
    this.flutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
  }

看,以上便是构造器的全貎了,设置了一个flutterJNI,添加了一个监听器。这个构造器在哪里被调用了呢?

  • FlutterEngine构造器中
  • FlutterView构造器中

另外,这个监听器的回调是在何时发生的呢?

public void onFirstFrame() {
    //...
    for (FlutterUiDisplayListener listener : flutterUiDisplayListeners) {
      listener.onFlutterUiDisplayed();
    }
  }

void onRenderingStopped() {
    //...
    for (FlutterUiDisplayListener listener : flutterUiDisplayListeners) {
      listener.onFlutterUiNoLongerDisplayed();
    }
  }

以上两个实例方法是定义在FlutterJNI中的。根据其方法名可以窥见监听回调的发生时机。再深入的是这两个实例方法的调用时机,此处不作介绍。

public void startRenderingToSurface(@NonNull Surface surface, boolean keepCurrentSurface) {
    //...
    if (this.surface != null && !keepCurrentSurface) {
      stopRenderingToSurface();
    }
    this.surface = surface;
    flutterJNI.onSurfaceCreated(surface);
  }

再来看渲染器如何启动渲染工作的。设置surface,然后通知flutterJNI有surface了。咱尝试着看一下flutterJNI是如何处理这一通知的。

public void onSurfaceCreated(@NonNull Surface surface) {
    //...
    nativeSurfaceCreated(nativeShellHolderId, surface);
  }

  private native void nativeSurfaceCreated(long nativeShellHolderId, @NonNull Surface surface);
static void SurfaceCreated(JNIEnv* env,
                           jobject jcaller,
                           jlong shell_holder,
                           jobject jsurface) {
  // ...
  auto window = fml::MakeRefCounted<AndroidNativeWindow>(
      ANativeWindow_fromSurface(env, jsurface));
  ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));
}
void PlatformViewAndroid::NotifyCreated(
    fml::RefPtr<AndroidNativeWindow> native_window) {
  //...
  PlatformView::NotifyCreated();
}

原来是通知了平台视图。那么之后又做了什么呢?咱先看一下这个函数的实现:

void PlatformView::NotifyCreated() {
  std::unique_ptr<Surface> surface;
  // Threading: We want to use the platform view on the non-platform thread.
  // Using the weak pointer is illegal. But, we are going to introduce a latch
  // so that the platform view is not collected till the surface is obtained.
  auto* platform_view = this;
  fml::ManualResetWaitableEvent latch;
  fml::TaskRunner::RunNowOrPostTask(
      task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() {
        surface = platform_view->CreateRenderingSurface();
        if (surface && !surface->IsValid()) {
          surface.reset();
        }
        latch.Signal();
      });
  latch.Wait();
  if (!surface) {
    FML_LOG(ERROR) << "Failed to create platform view rendering surface";
    return;
  }
  delegate_.OnPlatformViewCreated(std::move(surface));
}

说真的,我也看不懂啥意思,但是没关系,我可以瞎猜嘛,猜错了也不用付费的。如果读者有自己的想法,甚至与我相悖,也没事。下面是我瞎猜的内容:有一个信号量latch,它一直在等待,直到surface被造出来,然后执行最后一句代码。那surface是如何被造出来的呢?

std::unique_ptr<Surface> PlatformViewAndroid::CreateRenderingSurface() {
  if (!android_surface_) {
    return nullptr;
  }
  return android_surface_->CreateGPUSurface(
      android_context_->GetMainSkiaContext().get());
}

好了,到此处为止,可以知道它返回的是CreateGPUSurface函数的返回值。Flutter的渲染是直接由GPU处理的,而Skia是Google的图形渲染引擎。再详细的内容,这里不关心。不过,可以看一下这里的android_surface_是哪儿来的。

PlatformViewAndroid::PlatformViewAndroid(...) {
  if (android_context_) {
    //...
    android_surface_ = surface_factory_->CreateSurface();
    //...
  }
}
std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
  switch (android_context_->RenderingApi()) {
    case AndroidRenderingAPI::kSoftware:
      return std::make_unique<AndroidSurfaceSoftware>(android_context_,
                                                      jni_facade_);
    case AndroidRenderingAPI::kOpenGLES:
      return std::make_unique<AndroidSurfaceGL>(android_context_, jni_facade_);
    default:
      FML_DCHECK(false);
      return nullptr;
  }
}
enum class AndroidRenderingAPI {
  kSoftware,
  kOpenGLES,
};

好了,看清楚了,它是由工厂创建的,还分为两种方式进行创建,分别为kSoftwarekOpenGLES
接下来还剩上文中的void PlatformView::NotifyCreated()定义中的最后一句代码没说了。

void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
  //...
  auto ui_task = [engine = engine_->GetWeakPtr()] {
    if (engine) {
      engine->ScheduleFrame();
    }
  };
  //...
      sk_sp<GrDirectContext> resource_context =
          platform_view->CreateResourceContext();
      //...
}

调度帧、创建资源上下文。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值