主頁 > 移動端開發 > Flutter App啟動流程分析

Flutter App啟動流程分析

2021-10-21 08:13:58 移動端開發

首先手動創建一個hello_project的Flutter Project,再一步步跟著原始碼走

按照慣例我們首先查找是否有自定義的Application,發現Flutter Project沒有自定義Application,然后我們再來看MainActivity.kt

class MainActivity: FlutterActivity() {
}

MainActivity代碼無比簡單,我們繼續看FlutterActivity.java(Google官方都推Kotlin了,FlutterActivity居然還用Java…)

public class FlutterActivity extends Activity
    implements FlutterActivityAndFragmentDelegate.Host, LifecycleOwner 

MainActivity直接繼承自Activity,同時實作了兩個介面:LifecycleOwner(暴露系結生命周期的方法),FlutterActivityAndFragmentDelegate.Host,這里的Host主要是FlutterActivity作為宿主提供暴露各種方法,Host介面方法命名都比較簡單直觀,這里不做詳細解釋,

再來看onCreate方法

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    switchLaunchThemeForNormalTheme();
    super.onCreate(savedInstanceState);
		// 創建delegate,重點后面分析
    delegate = new FlutterActivityAndFragmentDelegate(this);
    // 1、onAttach 重點,內部初始化引擎邏輯
    delegate.onAttach(this);
    //onRestoreInstanceState,類似Activity中的onRestoreInstanceState方法,可以用來恢復資料
    delegate.onRestoreInstanceState(savedInstanceState);

    //系結生命周期
    lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);

    configureWindowForTransparency();
    //2、創建FlutterView,顯示到Activity上
    setContentView(createFlutterView());
    configureStatusBarForFullscreenFlutterExperience();
  }

這里我們重點關注兩步

  1. onAttach 內部創建初始化引擎
  2. createFlutterView() 創建FlutterView顯示到Activity上

下面著重一步一步來分析

onAttach

  void onAttach(@NonNull Context context) {
    ensureAlive();

    // 是否已經初始化過引擎
    if (flutterEngine == null) {
      //下面重點分析引擎初始化
      setupFlutterEngine();
    }

    if (host.shouldAttachEngineToActivity()) {
      //engine 與 activity系結
      Log.v(TAG, "Attaching FlutterEngine to the Activity that owns this delegate.");
      flutterEngine.getActivityControlSurface().attachToActivity(this, host.getLifecycle());
    }

    //初始化平臺插件,本質上,是將engine的 channel回呼與平臺的系統服務進行系結,如:震動、復制粘貼、聲音播放等...
    platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);

    //注冊插件,通過反射呼叫 “io.flutter.plugins.GeneratedPluginRegistrant.registerWith()”
    host.configureFlutterEngine(flutterEngine);
  }

setupFlutterEngine()

@VisibleForTesting
void setupFlutterEngine() {
    // 回傳FlutterEngine,如果為慷訓自動創建一個Engine
    flutterEngine = host.provideFlutterEngine(host.getContext());
    if (flutterEngine != null) {
      isFlutterEngineFromHost = true;
      return;
    }
    // 如果上面步驟都沒后獲取到flutterEngine的話,就創建一個FlutterEngine
    flutterEngine =
        new FlutterEngine(
            host.getContext(),
            host.getFlutterShellArgs().toArray(),
            /*automaticallyRegisterPlugins=*/ false,
            /*willProvideRestorationData=*/ host.shouldRestoreAndSaveState());
    isFlutterEngineFromHost = false;
  }

我們先來看一下FlutterEngine的理解:

  1. 是一個獨立的Flutter執行環境
  2. FlutterEngine 是一個容器,通過它可以在 Android 應用程式中運行 Dart 代碼,
  3. FlutterEngine 中的 Dart 代碼可以在后臺執行,也可以使用附帶的 FlutterRenderer 和 Dart 代碼將 Dart 端 UI 效果渲染到螢屏上,渲染可以開始和停止,從而允許 FlutterEngine 從 UI 互動轉移到僅進行資料處理,然后又回傳到 UI 互動的能力,
  4. 可能同時存在多個FlutterEngine執行Dart代碼,并且在單個Android應用程式中繪制UI,為了更好的記憶體性能特性,通過FlutterEngineGroup構造多個FlutterEngine,而不是直接通過FlutterEngine的建構式,
  5. 使用 FlutterEngine 執行 Dart 或 Flutter 代碼需要先通過 FlutterEngine 獲取 DartExecutor 參考,然后呼叫 DartExecutor 的executeDartEntrypoint(DartExecutor.DartEntrypoint)執行 Dart 代碼即可,同一個 FlutterEngine 實體中獲取的 DartExecutor 的executeDartEntrypoint(DartExecutor.DartEntrypoint)方法只能被呼叫一次,
  6. 要開始將 Flutter 內容渲染到螢屏上,請使用 getRenderer() 獲取 FlutterRenderer,然后附加一個 RenderSurface, 考慮使用 FlutterView 作為 RenderSurface,
  7. App 每個行程中創建第一個 FlutterEngine 實體的時候會加載 Flutter 引擎的原生庫并啟動 Dart VM(VM 存活生命周期跟隨行程),隨后同行程中其他的 FlutterEngines 將在同一個 VM 實體上運行,但在運行 DartExecutor 時將擁有自己的 Dart Isolate,每個 Isolate 都是一個獨立的 Dart 環境,除非通過 Isolate 埠,否則無法相互通信,
  8. App 每個行程中創建第一個 FlutterEngine 實體的時候會加載 Flutter 引擎的原生庫并啟動 Dart VM(VM 存活生命周期跟隨行程),隨后同行程中其他的 FlutterEngine 將在同一個 VM 實體上運行,但在運行 DartExecutor 時將擁有自己的 Dart Isolate,每個 Isolate 都是一個獨立的 Dart 環境,除非通過 Isolate 埠,否則無法相互通信,

最終整理對于一個多FlutterEngine的App來說,FlutterEngine,DartExecutor,Dart VM, Isloate關系如下:

在這里插入圖片描述

接下來我們繼續看FlutterEngine

public class FlutterEngine {
  //Flutter C/C++與平臺java層介面定義互動,Flutter 的引擎是用 C/C++ 構建的, Android Flutter 嵌入負責協調 Android 作業系統事件和應用程式用戶與 C/C++ 引擎的互動,
  @NonNull private final FlutterJNI flutterJNI;
  //表示 FlutterEngine 的渲染職責,
	//FlutterRenderer 與提供的 RenderSurface 協同作業,將 Flutter 像素繪制到 Android 視圖層次結構,
	//FlutterRenderer 管理用于渲染的紋理,并通過 JNI 將一些 Java 呼叫轉發到原生 Flutter 代碼, 相應的 RenderSurface 提供此渲染器繪制的 Android Surface,
	//io.flutter.embedding.android.FlutterSurfaceView 和 io.flutter.embedding.android.FlutterTextureView 是 RenderSurface 的實作
  @NonNull private final FlutterRenderer renderer;
  //Dart執行器,
  @NonNull private final DartExecutor dartExecutor;
  //用來管理安卓組件和Flutter plugins插件,
  @NonNull private final FlutterEngineConnectionRegistry pluginRegistry;
  //localization的安卓端實作插件,
  @NonNull private final LocalizationPlugin localizationPlugin;

  //一堆系統通道,負責與系統底層通信
  @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.
  // 管理平臺視圖,每個 io.flutter.app.FlutterPluginRegistry 都有一個平臺視圖控制器, 一個平臺視圖控制器最多可以附加到一個 Flutter 視圖
  @NonNull private final PlatformViewsController platformViewsController;
  // Engine Lifecycle.
  // 引擎宣告周期監聽
  @NonNull private final Set<EngineLifecycleListener> engineLifecycleListeners = new HashSet<>();
  //......

  //全引數的建構式,各種構造最終都走進這里
  public FlutterEngine(
      @NonNull Context context,
      @Nullable FlutterLoader flutterLoader,
      @NonNull FlutterJNI flutterJNI,
      @NonNull PlatformViewsController platformViewsController,
      @Nullable String[] dartVmArgs,
      boolean automaticallyRegisterPlugins,
      boolean waitForRestorationData) {
    //......
    //創建一個DartExecutor并將flutterJNI和安卓平臺的assetManager實體傳遞進去,
    this.dartExecutor = new DartExecutor(flutterJNI, assetManager);
    this.dartExecutor.onAttachedToJNI();
    //......
    //各種channel實體化
    accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI);
    deferredComponentChannel = new DeferredComponentChannel(dartExecutor);
    keyEventChannel = new KeyEventChannel(dartExecutor);
    lifecycleChannel = new LifecycleChannel(dartExecutor);
    localizationChannel = new LocalizationChannel(dartExecutor);
    mouseCursorChannel = new MouseCursorChannel(dartExecutor);
    navigationChannel = new NavigationChannel(dartExecutor);
    platformChannel = new PlatformChannel(dartExecutor);
    restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);
    settingsChannel = new SettingsChannel(dartExecutor);
    systemChannel = new SystemChannel(dartExecutor);
    textInputChannel = new TextInputChannel(dartExecutor);
    //......
    //插件實體化,
    this.localizationPlugin = new LocalizationPlugin(context, localizationChannel);

    this.flutterJNI = flutterJNI;
    if (flutterLoader == null) {
      flutterLoader = FlutterInjector.instance().flutterLoader();
    }
    //......
		// 引擎與四大組件的橋梁
    this.pluginRegistry =
        new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, flutterLoader);
	//默認就是自動注冊plugins的,可以通過清單檔案配置變更等,
    if (automaticallyRegisterPlugins && flutterLoader.automaticallyRegisterPlugins()) {
      registerPlugins();
    }
  }
  //......

  //注冊flutter專案根目錄下pubspec.yaml中依賴的所有flutter plugins,
  //Flutter tool會生成一個GeneratedPluginRegistrant的類,
  private void registerPlugins() {
    try {
      Class<?> generatedPluginRegistrant = Class.forName("io.flutter.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.");
    }
  }
  //......省略一堆屬性成員的get方法
}

總結下Flutter主要作用:

  1. FlutterEngineConnectionRegistry:創建組件與四大引擎生命周期的橋梁,方便插件根據各個組件的生命周期處理
  2. registerPlugins:通過反射注冊自定義插件
  3. 各種Channel的初始化,建立引擎與平臺系統之間的橋梁
  4. DartExecutor:Dart執行環境創建,onAttachedToJNI之后,DartExecutor將開始處理與Dart背景關系之間的雙向通行,BinaryMessenger(向Dart發送訊息),PlatformMessageHandler,它接受來自Dart的訊息
  5. FlutterRenderer:渲染環境的創建

到此FlutterEngine基本創建完成,內部細節不做詳解,下面再來分析下createFlutterView

createFlutterView

createFlutterView走到了FlutterActivityAndFragmentDelegate的onCreateView方法

 @NonNull
  View onCreateView(
      LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    Log.v(TAG, "Creating FlutterView.");
    ensureAlive();

    if (host.getRenderMode() == RenderMode.surface) {
      FlutterSurfaceView flutterSurfaceView =
          new FlutterSurfaceView(
              host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent);

      // 允許自定義flutterSurfaceView
      host.onFlutterSurfaceViewCreated(flutterSurfaceView);

      // 創建擁有 FlutterSurfaceView 的 FlutterView,
      flutterView = new FlutterView(host.getActivity(), flutterSurfaceView);
    } else {
      FlutterTextureView flutterTextureView = new FlutterTextureView(host.getActivity());

      // 允許自定義flutterTextureView
      host.onFlutterTextureViewCreated(flutterTextureView);

      // 創建擁有 FlutterTextureView 的 FlutterView,
      flutterView = new FlutterView(host.getActivity(), flutterTextureView);
    }

    // 添加偵聽器以在 Flutter 呈現其第一幀時收到通知,
    flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener);

    flutterSplashView = new FlutterSplashView(host.getContext());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
      flutterSplashView.setId(View.generateViewId());
    } else {
      flutterSplashView.setId(486947586);
    }
    flutterSplashView.displayFlutterViewWithSplash(flutterView, host.provideSplashScreen());

    Log.v(TAG, "Attaching FlutterEngine to FlutterView.");
    flutterView.attachToFlutterEngine(flutterEngine);
    return flutterSplashView;
  }

該方法主要完成四個任務:

  1. 在 View 層次結構中創建一個新的 FlutterView
  2. 添加一個 FlutterUiDisplayListener
  3. 將 FlutterEngine 附加到新的 FlutterView
  4. flutterSplashView(主要作用是在 FlutterView render 渲染出來之前顯示一個SplashScreen),類似于過度圖

我們在簡單看下FlutterView,FlutterView是一個Android 原生的控制元件,繼承自FrameLayout,它之所以顯示的是Flutter UI,完全是依賴于FlutterSurfaceView和FlutterTextureView,而FlutterSurfaceView和FlutterTextureView這兩個View的繪制內容又是來自于FlutterEngine提供,

FlutterView原始碼分析,我們后面再來單獨講…

結尾

? 講到這里,我們基本上了解了Flutter啟動的大致流程,其實無論是FlutterActivity還是FlutterFragment都是通過代理類FlutterActivityAndFragmentDelegate來封裝呼叫Flutter的各種行為,

? 下文我們在一起看看FlutterView是如何作業,Flutter UI是如何顯示到原生界面上的,,,,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/328036.html

標籤:其他

上一篇:Android apk加固

下一篇:Android學習指南 — Android基礎知識匯總

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more