原生Android集成Flutter混合開發

原生Android和Flutter集成主要有兩種方案:

1.源碼集成:官方提供的源碼集成方案
2.產物集成:Flutter 項目單獨開發,開發完成後發佈成 aar 包或者 iOS 的 framework 形式,原生項目依賴 Flutter 輸出的文件即可。
3.鹹魚團隊的FlutterBoost 方案。FlutterBoost地址

環境

首先確認環境是否正確:
這裏重點關注一下Flutter version的版本。在後面介紹集成開發的時候,不同的Flutter版本有差別。

flutter doctor -v

下面是我的環境信息:
在這裏插入圖片描述

集成

創建Android項目

略過新建 Native Android項目的流程。

注意點:
(1)現在創建的Flutter module默認是支持Android X的,所以如果想在現有的項目中集成Flutter module需要把support包替換成Android x。所有這裏是通過新建一個 Native Android項目(默認支持Android x)來演示混合開發流程。
(2)配置信息,需要在app/build.gradle裏設置

android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}

創建Flutter module

  1. 切換 flutter 的 channel 到 master (master 分支下是 flutter 的 preview 版本)
flutter channel master
  1. 創建 flutter module項目
    module後面是新建的Flutter module的名稱。
flutter create -t module flutter_test
  1. Flutter module的目錄結構:
    (1)在 flutter 的模塊項目中包含有一個隱藏的 .android 和 .ios 目錄這個目錄下是可運行的 Android 和 iOS 項目。
    (2)flutter代碼寫在 lib下,注意在 .android 和 .ios 目錄下都有一個 Flutter 目錄,這個是我們 flutter 的庫項目了。也就是Android 用來生成 aar,iOS 用來生產 framework 的庫。
    (3 Flutter Application項目是沒有.android 和.ios目錄的。Flutter Application項目下對應的是android和ios這兩個目錄。
    在這裏插入圖片描述
  2. git管理Flutter module
    (1)把項目使用 git 管理起來,後面會在 native 項目中以submodule的形式引入native項目。
    略過git上傳到遠程git倉庫的過程。
    (2)重點關注一下gitignore文件的編輯
    編輯一下項目下的 .gitignore 文件,需要把項目下的 .ios 和 .android 忽略掉。
    這裏有個坑,有的文章說要把.packages也忽略掉,但是根據我的實驗是不行的,建議大家還是把.packages通過git管理起來。
    (3)我的gitignore配置信息
.DS_Store
.dart_tool/
.pub/
.idea/
.vagrant/
.sconsign.dblite
.svn/
*.swp
profile
DerivedData/
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
build/
.ios/Flutter/Generated.xconfig
.flutter-plugins

Native Android 項目集成 Flutter

  1. native android 項目集成 Flutter
    (1)將目錄切換到native android代碼目錄下
    (2)將Flutter module添加到native android中。
git submodule add flutter module的倉庫地址
git submodule update
  1. 在native android根目錄的 settings.gradle中添加如下配置
    這裏的路徑使用的是相對於native android 項目的路徑。
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir,
        'flutter_test/.android/include_flutter.groovy'
))
  1. 在native android項目的 app 目錄下的 build.gradle 文件中添加 Flutter 庫的依賴
implementation project(':flutter')
  1. 從新rebuild項目以後,在native android項目目錄下會多一個flutter module子項目。

代碼編寫

通過native怎麼加載flutter widget呢?Flutter提供了以下集中方法。(Flutter不同版本存在差異)
6.1 通過FlutterFragment類
直接在對應的native activity 佈局文件中添加FlutterFragment即可。

 <fragment
            android:id="@+id/flutterfragment"
            android:name="io.flutter.embedding.android.FlutterFragment"
            android:layout_width="300dp"
            android:layout_height="500dp" />

6.2 通過FlutterActivity類
在 AndroidManifest.xml 中註冊

<activity
                android:name="io.flutter.embedding.android.FlutterActivity"
                android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
                android:exported="true"
                android:hardwareAccelerated="true"
                android:windowSoftInputMode="adjustResize" />

默認啓動方式:默認路由爲 ‘/’

import io.flutter.embedding.android.FlutterActivity
val intent = FlutterActivity.createDefaultIntent(this)
startActivity(intent)

啓動到指定路由

 val customFlutter = FlutterActivity.withNewEngine()
            .initialRoute("newRoute")
            .build(this)
        startActivity(customFlutter)

6.3 通過FlutterView類
通過該類沒有實現效果,待研究

 FlutterView flutterView = new FlutterView(this);
        FrameLayout frameLayout = findViewById(R.id.framelayout);
        frameLayout.addView(flutterView);
       //創建一個 FlutterView 就可以了,這個時候還不會渲染。
      //調用下面代碼後纔會渲染
        flutterView.attachToFlutterEngine(new FlutterEngine(this));

集成中經歷的坑

  1. finished with non-zero exit value 1
Process 'command '/Users/mtdp/Documents/Flutter/flutter/bin/flutter'' finished with non-zero exit value 1

造成這個的原因是缺少.packages文件,所有在通過git管理flutter module的時候,儘量把.packages保留。
2. 廢棄類
Flutter默認在某個版本以後已經不支持facade了。
Flutter version 1.7.8+hotfix.4版本還是支持的,具體從那個版本移除了,還不清楚。

io.flutter.facade.*

ps:以前的方式(deprecated) ( io.flutter.facade )
通過使用 Flutter.createView:

View flutterView = Flutter.createView(
      MainActivity.this,
      getLifecycle(),
      "route1"
    );
    FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);
    layout.leftMargin = 100;
    layout.topMargin = 200;
    addContentView(flutterView, layout);

通過使用 Flutter.createFragment:

 FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
    tx.replace(R.id.someContainer, Flutter.createFragment("route1"));
    tx.commit();

git submodule刪除後重新添加問題

  1. 重新添加git 子模塊出現的問題:
A git directory for 'formRenderLib' is found locally with remote(s):
  origin   xxxxxx
If you want to reuse this local git directory instead of cloning again from
  xxxx
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

說明沒有刪除乾淨之前的module
2. 解決方法:
2.1 在native android主項目目錄下,刪除指定模塊的文件

 git rm --cached module名稱 

2.2 打開主項目目錄下 .gitmodules 刪除和submodule相關的配置信息
2.3 打開主項目目錄下 .git/config 文件刪除和submodule相關的配置信息
2.4 刪除.git下的緩存模塊

rm -rf .git/modules/submodule名稱

2.5 添加子模塊

git submodule add submodule的git倉庫
發佈了38 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章