原生应用中混编 Flutter
分别创建iOS、android空壳项目,iOS集成pod
pod init
pod install
Flutter 混编方案介绍
将原生工程作为 Flutter 工程的子工程,由 Flutter 统一管理。这种模式,就是统一管理模式。三端(Android、iOS、Flutter)代码耦合严重,相关工具链耗时也随之大幅增长,导致开发效率降低。
将 Flutter 工程作为原生工程共用的子模块,维持原有的原生工程管理方式不变。这种模式,就是三端分离模式。三端工程分离模式的关键是抽离 Flutter 工程,将不同平台的构建产物依照标准组件化的形式进行管理,即 Android 使用 aar、iOS 使用 pod。
集成 Flutter
原生工程对 Flutter 的依赖主要分为两部分:
Flutter 库和引擎,也就是 Flutter 的 Framework 库和引擎库;
Flutter 工程,也就是我们自己实现的 Flutter 模块功能,主要包括 Flutter 工程 lib 目录下的 Dart 代码实现的这部分功能。
flutter create -t module flutter_library
Flutter 模块有一个细微的变化:Android 工程下多了一个 Flutter 目录,这个目录下的 build.gradle 配置就是我们构建 aar 的打包配置。
Android 模块集成
首先在 Flutter_library 的根目录下,执行 aar 打包构建命令:
flutter build apk --debug
如果是构建 release 产物,只需要把 debug 换成 release 就可以了。其次,打包构建的 flutter-debug.aar 位于.android/Flutter/build/outputs/aar/ 目录下,我们把它拷贝到原生 Android 工程 AndroidDemo 的 app/libs 目录下,并在 App 的打包配置 build.gradle 中添加对它的依赖:
...
repositories {
flatDir {
dirs 'libs' // aar 目录
}
}
dependencies {
...
implementation(name: 'flutter-debug', ext: 'aar')//Flutter 模块 aar
...
}
activity_main_xml添加
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
Sync 一下,Flutter 模块就被添加到了 Android 项目中。
再次,我们试着改一下 MainActivity.java 的代码,把它的 contentView 改成 Flutter 的 widget:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//FlutterFragment fragment=new FlutterFragment();
FlutterFragment fragment=FlutterFragment.withNewEngine().initialRoute("defaultRoute").build();
getSupportFragmentManager().beginTransaction().add(R.id.content, fragment).commit();
}
iOS 模块集成
在 iOS 平台,原生工程对 Flutter 的依赖分别是:
Flutter 库和引擎,即 Flutter.xcframework;
Flutter 工程的产物,即 App.xcframework。
首先我们在 Flutter_library 的根目录下,执行 iOS 打包构建命令:
flutter build ios --debug
把 debug 换成 release 就可以构建 release 产物
iOS 项目的podfile添加如下
//添加
flutter_application_path = '../flutter_library'
load File.join(flutter_application_path, '.iOS', 'Flutter', 'podhelper.rb')
target 'iOSDemo' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
//添加
install_all_flutter_pods(flutter_application_path)
...
end
iOS代码
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow * window;
@end
#import "AppDelegate.h"
#import <Flutter/Flutter.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
FlutterViewController *vc = [[FlutterViewController alloc]init];
[vc setInitialRoute:@"defaultRoute"]; //路由标识符
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
return YES;
}
@end