原生Android和Flutter集成主要有兩種方案:
1.源碼集成:官方提供的源碼集成方案
2.產(chǎn)物集成:Flutter 項(xiàng)目單獨(dú)開發(fā)浓体,開發(fā)完成后發(fā)布成 aar 包或者 iOS 的 framework 形式泡挺,原生項(xiàng)目依賴 Flutter 輸出的文件即可。
3.咸魚團(tuán)隊(duì)的FlutterBoost 方案命浴。FlutterBoost地址
環(huán)境
首先確認(rèn)環(huán)境是否正確:
這里重點(diǎn)關(guān)注一下Flutter version的版本娄猫。在后面介紹集成開發(fā)的時(shí)候,不同的Flutter版本有差別生闲。
flutter doctor -v
下面是我的環(huán)境信息:
集成
創(chuàng)建Android項(xiàng)目
略過新建 Native Android項(xiàng)目的流程媳溺。
注意點(diǎn):
(1)現(xiàn)在創(chuàng)建的Flutter module默認(rèn)是支持Android X的,所以如果想在現(xiàn)有的項(xiàng)目中集成Flutter module需要把support包替換成Android x碍讯。所有這里是通過新建一個(gè) Native Android項(xiàng)目(默認(rèn)支持Android x)來演示混合開發(fā)流程悬蔽。
(2)配置信息,需要在app/build.gradle里設(shè)置
android {
//...
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
創(chuàng)建Flutter module
- 切換 flutter 的 channel 到 master (master 分支下是 flutter 的 preview 版本)
flutter channel master
- 創(chuàng)建 flutter module項(xiàng)目
module后面是新建的Flutter module的名稱冲茸。
flutter create -t module flutter_test
- Flutter module的目錄結(jié)構(gòu):
(1)在 flutter 的模塊項(xiàng)目中包含有一個(gè)隱藏的 .android 和 .ios 目錄這個(gè)目錄下是可運(yùn)行的 Android 和 iOS 項(xiàng)目屯阀。
(2)flutter代碼寫在 lib下,注意在 .android 和 .ios 目錄下都有一個(gè) Flutter 目錄轴术,這個(gè)是我們 flutter 的庫項(xiàng)目了难衰。也就是Android 用來生成 aar,iOS 用來生產(chǎn) framework 的庫逗栽。
(3 Flutter Application項(xiàng)目是沒有.android 和.ios目錄的盖袭。Flutter Application項(xiàng)目下對(duì)應(yīng)的是android和ios這兩個(gè)目錄。
- git管理Flutter module
(1)把項(xiàng)目使用 git 管理起來,后面會(huì)在 native 項(xiàng)目中以submodule的形式引入native項(xiàng)目鳄虱。
略過git上傳到遠(yuǎn)程git倉庫的過程弟塞。
(2)重點(diǎn)關(guān)注一下gitignore文件的編輯
編輯一下項(xiàng)目下的 .gitignore 文件,需要把項(xiàng)目下的 .ios 和 .android 忽略掉拙已。
這里有個(gè)坑决记,有的文章說要把.packages也忽略掉,但是根據(jù)我的實(shí)驗(yàn)是不行的倍踪,建議大家還是把.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 項(xiàng)目集成 Flutter
- native android 項(xiàng)目集成 Flutter
(1)將目錄切換到native android代碼目錄下
(2)將Flutter module添加到native android中。
git submodule add flutter module的倉庫地址
git submodule update
- 在native android根目錄的 settings.gradle中添加如下配置
這里的路徑使用的是相對(duì)于native android 項(xiàng)目的路徑建车。
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir,
'flutter_test/.android/include_flutter.groovy'
))
- 在native android項(xiàng)目的 app 目錄下的 build.gradle 文件中添加 Flutter 庫的依賴
implementation project(':flutter')
- 從新rebuild項(xiàng)目以后扩借,在native android項(xiàng)目目錄下會(huì)多一個(gè)flutter module子項(xiàng)目。
代碼編寫
通過native怎么加載flutter widget呢缤至?Flutter提供了以下集中方法潮罪。(Flutter不同版本存在差異)
6.1 通過FlutterFragment類
直接在對(duì)應(yīng)的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 中注冊(cè)
<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" />
默認(rèn)啟動(dòng)方式:默認(rèn)路由為 '/'
import io.flutter.embedding.android.FlutterActivity
val intent = FlutterActivity.createDefaultIntent(this)
startActivity(intent)
啟動(dòng)到指定路由
val customFlutter = FlutterActivity.withNewEngine()
.initialRoute("newRoute")
.build(this)
startActivity(customFlutter)
6.3 通過FlutterView類
通過該類沒有實(shí)現(xiàn)效果领斥,待研究
FlutterView flutterView = new FlutterView(this);
FrameLayout frameLayout = findViewById(R.id.framelayout);
frameLayout.addView(flutterView);
//創(chuàng)建一個(gè) FlutterView 就可以了嫉到,這個(gè)時(shí)候還不會(huì)渲染。
//調(diào)用下面代碼后才會(huì)渲染
flutterView.attachToFlutterEngine(new FlutterEngine(this));
集成中經(jīng)歷的坑
- finished with non-zero exit value 1
Process 'command '/Users/mtdp/Documents/Flutter/flutter/bin/flutter'' finished with non-zero exit value 1
造成這個(gè)的原因是缺少.packages文件月洛,所有在通過git管理flutter module的時(shí)候屯碴,盡量把.packages保留。
- 廢棄類
Flutter默認(rèn)在某個(gè)版本以后已經(jīng)不支持facade了膊存。
在Flutter version 1.7.8+hotfix.4
版本還是支持的,具體從那個(gè)版本移除了忱叭,還不清楚隔崎。
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 子模塊出現(xiàn)的問題:
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.1 在native android主項(xiàng)目目錄下,刪除指定模塊的文件
git rm --cached module名稱
2.2 打開主項(xiàng)目目錄下 .gitmodules 刪除和submodule相關(guān)的配置信息
2.3 打開主項(xiàng)目目錄下 .git/config 文件刪除和submodule相關(guān)的配置信息
2.4 刪除.git下的緩存模塊
rm -rf .git/modules/submodule名稱
2.5 添加子模塊
git submodule add submodule的git倉庫