原生Android集成Flutter混合開發(fā)

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

1.源碼集成:官方提供的源碼集成方案

2.產(chǎn)物集成:Flutter 項目單獨開發(fā),開發(fā)完成后發(fā)布成 aar 包或者 iOS 的 framework 形式,原生項目依賴 Flutter 輸出的文件即可。

3.咸魚團隊的FlutterBoost 方案。FlutterBoost地址

環(huán)境

首先確認(rèn)環(huán)境是否正確:
這里重點關(guān)注一下Flutter version的版本。在后面介紹集成開發(fā)的時候,不同的Flutter版本有差別。

flutter doctor -v

下面是我的環(huán)境信息:


在這里插入圖片描述

集成

創(chuàng)建Android項目

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

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

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

創(chuàng)建Flutter module

  1. 切換 flutter 的 channel 到 master (master 分支下是 flutter 的 preview 版本)
flutter channel master
  1. 創(chuàng)建 flutter module項目
    module后面是新建的Flutter module的名稱。
flutter create -t module flutter_test
  1. Flutter module的目錄結(jié)構(gòu):

(1)在 flutter 的模塊項目中包含有一個隱藏的 .android 和 .ios 目錄這個目錄下是可運行的 Android 和 iOS 項目。

(2)flutter代碼寫在 lib下,注意在 .android 和 .ios 目錄下都有一個 Flutter 目錄,這個是我們 flutter 的庫項目了。也就是Android 用來生成 aar,iOS 用來生產(chǎn) framework 的庫。

(3 Flutter Application項目是沒有.android 和.ios目錄的。Flutter Application項目下對應(yīng)的是android和ios這兩個目錄。

在這里插入圖片描述
  1. git管理Flutter module

(1)把項目使用 git 管理起來,后面會在 native 項目中以submodule的形式引入native項目。
略過git上傳到遠(yuǎn)程git倉庫的過程。

(2)重點關(guān)注一下gitignore文件的編輯

編輯一下項目下的 .gitignore 文件,需要把項目下的 .ios 和 .android 忽略掉。
這里有個坑,有的文章說要把.packages也忽略掉,但是根據(jù)我的實驗是不行的,建議大家還是把.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類
直接在對應(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 中注冊

<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)啟動方式:默認(rèn)路由為 '/'

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類
通過該類沒有實現(xiàn)效果,待研究

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

集成中經(jīng)歷的坑

  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保留。

  1. 廢棄類
    Flutter默認(rèn)在某個版本以后已經(jīng)不支持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 子模塊出現(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

  1. 解決方法:

    2.1 在native android主項目目錄下,刪除指定模塊的文件

 git rm --cached module名稱 

2.2 打開主項目目錄下 .gitmodules 刪除和submodule相關(guān)的配置信息

2.3 打開主項目目錄下 .git/config 文件刪除和submodule相關(guān)的配置信息

2.4 刪除.git下的緩存模塊

rm -rf .git/modules/submodule名稱

2.5 添加子模塊

git submodule add submodule的git倉庫
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容