Flutter 1.12混合開發實踐

TNT君發表於2020-03-16

前言

Flutter 1.12版本官方推出了Add-to-App的整合方式,將現有的Flutter應用快速整合到現有的原生應用中。詳情見官網 flutter.dev/docs/develo…,Flutter 1.12在整合方式上相較於之前版本有較大的改動,以及外掛註冊、部分API均有改動。文章將以Flutter 1.12為基礎,動手實踐Android平臺的混合開發。

混合開發中Flutter Engine問題

Flutter官方整合方式,在開啟新的Flutter頁面時會重新建立Engine。官方雖然提供了CachedEngine,但是在初始化路由之後,無法再更改路由。如果存在多個Flutter頁面需要在不同的地方開啟,那麼依然需要建立不同的Engine,或者通過原生與Flutter通訊進行頁面的切換。Engine的重複建立未能及時釋放會導致啟動時間變長及加大記憶體的壓力,因此將Engine進行單例化處理是非常有必要的。國內鹹魚團隊開源了FlutterBoost技術方案,正解決了現有的問題。

建立Flutter專案

  • 要使用Flutter 1.12的Add-to-App整合方式,首先我們需要建立一個Flutter module。

Flutter 1.12混合開發實踐

  • 然後我們需要在專案中新增對FlutterBoost的依賴
flutter_boost: ^1.12.13
複製程式碼
  • 建立兩個Flutter頁面,並在啟動方法中初始化FlutterBoost
@override
  void initState() {
    super.initState();
    FlutterBoost.singleton.registerPageBuilders({
      //配置頁面路由資訊
      "first_page": (context, params, _) => FirstPage(),
      "second_page": (context, params, _) => SecondPage()
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "FlutterBoostDemo",
      builder: FlutterBoost.init(),
      home: Container(),
    );
  }
複製程式碼
  • 打包Android平臺產物,採用AAR的整合方式

Flutter 1.12混合開發實踐

  • 打包產物會生成到專案的build/host/outputs/repo目錄下

Flutter 1.12混合開發實踐

整合原生專案

  • 在原生Android專案的app/build.gradle中新增以下程式碼
repositories {
  maven {
    //此處為剛才Flutter打包產物的目錄,實際路徑以本地為準
    url '/Users/fengyuanjun/Desktop/test_module/build/host/outputs/repo'
  }
  maven {
    url 'http://download.flutter.io'
  }
}
複製程式碼
dependencies {
  debugImplementation 'com.example.test_module:flutter_debug:1.0'
  profileImplementation 'com.example.test_module:flutter_profile:1.0'
  releaseImplementation 'com.example.test_module:flutter_release:1.0'
}
複製程式碼
  • 同步Gradle之後,在Application中配置FlutterBoost
class MyApp: Application(){
    override fun onCreate() {
        super.onCreate()
        initFlutterBoost();
    }

    private fun initFlutterBoost() {
        FlutterMain.startInitialization(this)
        val platform = FlutterBoost
            .ConfigBuilder(this,null)
            .isDebug(BuildConfig.DEBUG)
            .whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
            .renderMode(FlutterView.RenderMode.texture)
            .build()
        FlutterBoost.instance().init(platform)
    }
}
複製程式碼
  • 我們可以通過這樣的方式來啟動Flutter頁面
val intent = BoostFlutterActivity
      .withNewEngine()
      .url("first_page")
      .build(this)
startActivity(intent)
複製程式碼
  • 在實際開發中,我們更希望不同的Flutter頁面之間使用不同的Activity作為載體,來完成一些特定的互動操作,避免在一個檔案中整合大量的原生與Flutter的互動操作。因此我們需要定製BoostFlutterActivity。
//此處為BoostFlutterActivity內部實現
public String getContainerUrl() {
    return this.getIntent().hasExtra("url") ? this.getIntent().getStringExtra("url") : "";
}
複製程式碼
  • 通過閱讀BoostFlutterActivity原始碼,我們可以看到獲得頁面Url實際是通過獲取Intent物件中的url引數來獲取,因此我們只需要重寫此方法就可以實現需求。
class FirstPage: BoostFlutterActivity() {
    //通過重寫其他方法或進一步的封裝可以實現更多的功能
    //在此只做最基礎的頁面跳轉功能
    override fun getContainerUrl(): String {
        return "first_page"
    }
}
複製程式碼
  • 同樣的方式建立一個SecondActivity,並在首頁新增啟動入口。最終實現效果如下

Flutter 1.12混合開發實踐

Flutter 1.12混合開發實踐

Flutter 1.12混合開發實踐

總結

Flutter 1.12結合Flutter Boost的混合開發基礎實踐就結束了,後續再給大家帶來Flutter和原生間互動以及實際專案的實戰開發。Flutter官方和FlutterBoost還提供了其他整合方式和更高階的用法。感興趣的可以自行了解學習。

參考資料

Flutter官方: flutter.dev

FlutterBoost: github.com/alibaba/flu…

Flutter中文網: flutterchina.club

掘金Flutter社群: juejin.im/tag/Flutter

相關文章