Android原生項目集成flutter項目混合開發
方案挑選:
目前主要有兩種集成方式:
1、源碼集成:就是谷歌官方提供的方案( https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps )
2、 產物集成: Flutter項目單獨開發,開發完成後發佈成安卓以aar包,iOS的framework形式,原生項目依賴flutter輸出的製品就可以了,具體可以看閒魚的文章,他們就是這麼幹的,借用網上的一張圖
兩種方案各有優劣,鑑於我們項目參與人數衆多,如果採用源碼集成的方式,所有人都得配相應的環境和了解相關的知識,顯然成本較高,所有我們選擇了第二種方式,專門幾個人去做flutter項目然後以AAR包的方式集成到項目中來
這篇文章裏我兩種都嘗試一下,當然我是安卓這邊的嘗試
方式一、源碼集成的方式,項目裏直接引入flutter module
直接從AS的圖形界面導入已經新建的flutter module嘗試失敗
這樣導入flutter module失敗
正確打開方式:
1、使用Android Studio來創建Flutter Module(放在原生的同級目錄)
1、 依次點擊左上角的File --> New --> New Flutter Project
2、然後選擇Flutter Module。
如圖:
2、在項目的根目錄settings.gradle文件中配置:
include ':app'
include ':flutter_module'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'主項目名稱/flutter_module名稱/.android/include_flutter.groovy'))
3、在app下的gradle文件中添加
implementation project(':flutter')
完成這三步就順利完成在原生項目中集成flutter module了
安卓原生界面跳轉到flutter界面有兩種方式,一種是使用flutterView,另一種是使用 FlutterFragment ,這裏我選擇了前者
先新建一個activity,FlutterViewActivty(隨意命名),在oncreate方法中加入以下代碼
private fun initView() {
val flutterView: View = Flutter.createView(this, lifecycle, "flutter Route1")
val layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
addContentView(flutterView, layoutParams)
}
Flutter.createView()
方法返回的是一個FlutterView,它繼承自View,我們可以把它當做一個普通的View,調用addContentView()
方法將這個View添加到Activity的contentView中。我們注意到Flutter.createView()
方法的第三個參數傳入了"flutter Route1"字符串,表示路由名稱,它確定了Flutter中要顯示的Widget,接下來需要在之前創建好的Flutter Module中編寫邏輯了,修改main.dart文件中的代碼
``
Widget _widgetForRoute(String route) {
switch (route) {
case "flutter Route1":
return Scaffold(
appBar: AppBar(
title: Text("test native"),
),
body: Center(
child: Text('flutter 頁面,route=$route'),
),
);
default:
return Center(
child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
);
}
}
在runApp()方法中通過window.defaultRouteName可以獲取到我們在Flutter.createView()方法中傳入的路由名稱,即"flutter Route1",之後編寫了一個_widgetForRoute()方法,根據傳入的route字符串顯示相應的Widget。
最後在Mainacivity中加入跳轉事件
switch (v.getId()) {
case R.id.btn_flutter:
Intent intent = new Intent(MainActivity.this, FlutterViewActivity.class);
startActivity(intent);
break;
}
大功告成!!
但是發現原生的標題欄還在,在style中加入透明標題欄樣式
<style name="FlutterTheme" parent="AppTheme.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
順利完成,如圖,點擊跳轉的時候會有黑屏一下的現象,不過沒事,這是debug情況纔會有的,debug有一些調試的預加載,打了release包之後就沒有這個現象了
方案二、AAR方式集成
1、Android 原工程需要使用 java 8 編譯
在 工程的 build.gradle 裏面,android {} 下修改
android {
//...
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
2、生成 aar 文件
通過集成 arr 的方式需要先生成 Flutter Module 的 arr,在 Flutter Module 的根目錄下運行以下命令
flutter build aar
3、使用 aar
主工程的 build.gradle repositories 閉包 裏面加入
flatDir {
dirs 'libs' // aar目錄
}
然後把AAR包複製到libs目錄下面, app 的 build.gradle 裏面添加依賴
implementation (name:'flutter-release-old',ext:'aar')
跳轉的代碼和方式一一樣不用動,編譯運行之後成功
參考:
https://www.jianshu.com/p/5ef007d83b34
https://www.jianshu.com/p/7b6522e3e8f1