原生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
- 切換 flutter 的 channel 到 master (master 分支下是 flutter 的 preview 版本)
flutter channel master
- 創建 flutter module項目
module後面是新建的Flutter module的名稱。
flutter create -t module flutter_test
- 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這兩個目錄。
- 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
- native android 項目集成 Flutter
(1)將目錄切換到native android代碼目錄下
(2)將Flutter module添加到native android中。
git submodule add flutter module的倉庫地址
git submodule update
- 在native android根目錄的 settings.gradle中添加如下配置
這裏的路徑使用的是相對於native android 項目的路徑。
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir,
'flutter_test/.android/include_flutter.groovy'
))
- 在native android項目的 app 目錄下的 build.gradle 文件中添加 Flutter 庫的依賴
implementation project(':flutter')
- 從新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));
集成中經歷的坑
- 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刪除後重新添加問題
- 重新添加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倉庫