Flutter - Add Flutter module to Native app
TLDR;
Bài hướng dẫn sau tập trung cho hai mục tiêu:
- Trong trường hợp bạn có sẵn source code Android native (Java, Kotlit) và iOS (Objective-C, Swift) và mong muốn tiếp tục phát triển thêm tính năng mới bằng Flutter framework thay vì phải maintain và phát triển trên 2 source code khác nhau.
- Trong trường hợp bạn muốn kếp hợp 2 ứng dụng với nhau, một được build bằng Native, hai được build bằng Flutter
Prepare
- Đảm bảo bạn đã setup thành công môi trường dev cho Android, iOS và Flutter.
- Môi trường phát triển của bạn phải đáp ứng các yêu cầu hệ thống macOS dành cho Flutter:
- Có cài đặt Xcode, hỗ trợ iOS 11 trở lên.
- Bạn sẽ cần CocoaPods phiên bản 1.10 trở lên.
- Module organization
some/path/project_workspace
├── my_flutter/
│ └── .ios/
│ | └── Flutter/
│ | └── podhelper.rb
| └── .android/
| | └── Flutter
| | └── app
| | └── include_flutter.groovy
| └── pubspec.yaml
└── iOSApp (com.example.app)/
| └── Podfile
└── AndroidApp (com.example.app)/
└── settings.gradle
Để có được cấu trúc trên, tại some/path/project_workspace
tạo flutter module bằng cmd sau
flutter create -t module --org com.example my_flutter
Sau khi module được tạo, bạn mở file pubspec.yaml
trong my_flutter
và chỉnh sửa bundle id cho native app
module:
androidX: true
androidPackage: com.example.app
iosBundleIdentifier: com.example.app
Setup Android project
Notes
- Ứng dụng Android của bạn có thể hỗ trợ các kiến trúc như
mips
hoặcx86
. Flutter hiện chỉ hỗ trợ xây dựng các thư viện chox86_64
,armeabi-v7a
vàarm64-v8a
. Chỉnh sửa fileAndroidApp/app/build.gradle
android {
//...
defaultConfig {
ndk {
// Filter for architectures supported by Flutter.
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
}
}
}
- Up to dated các dependencies trước khi thực hiện việc thêm Flutter module
Add the Flutter module as a dependency
- Thêm Flutter module như là một subproject trong
AndroidApp/settings.gradle
.
// Include the host app project.
include ':app' // assumed existing content
setBinding(new Binding([gradle: this])) // new
evaluate(new File( // new
settingsDir.parentFile, // new
'my_flutter/.android/include_flutter.groovy' // new
)) // new
- Thêm Flutter module dependency vào
AndroidApp/app/build.gradle
vàsync
lại project
dependencies {
implementation project(':flutter')
}
Add a Flutter screen to an Android app
- Thêm
FlutterActivity
vàoAndroidManifest.xml
<activity
android:name="io.flutter.embedding.android.FlutterActivity" />
- Gọi mở Flutter module từ native
startActivity(
FlutterActivity
.withNewEngine()
.build(currentActivity)
);
Setup iOS project
Add the Flutter module as a dependency with CocoaPods
Nếu iOSApp chưa có Podfile, chạy cmd pod init
ở thử mục iOSApp để tạo.
1. Thêm các dòng sau vào của bạn iOSApp/Podfile:
platform :ios, '11.0'
flutter_application_path = '../my_flutter' # new
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') # new
2. Gọi install_all_flutter_pods(flutter_application_path) trong mỗi target
target 'MyApp' do
install_all_flutter_pods(flutter_application_path)
end
3. Gọi flutter_post_install(installer) trong Podfile’s post_install
post_install do |installer|
flutter_post_install(installer) if defined?(flutter_post_install)
end
4. Run pod install
.
Add a Flutter screen to an iOS app
- Trong
AppDelegate.swift
khai báoFlutterEngine
import UIKit
import Flutter //new
// The following library connects plugins with iOS platform code to this app.
import FlutterPluginRegistrant //new
@UIApplicationMain
class AppDelegate: UIApplicationDelegate {
lazy var flutterEngine = FlutterEngine(name: "my_flutter_engine") //new
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Runs the default Dart entrypoint with a default Flutter route.
flutterEngine.run(); //new
// Connects plugins with iOS platform code to this app.
GeneratedPluginRegistrant.register(with: self.flutterEngine); //new
return super.application(application, didFinishLaunchingWithOptions: launchOptions);
}
}
- Hiển thị FlutterViewController với FlutterEngine vừa tạo ở trên
let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
present(flutterViewController, animated: true, completion: nil)
Done, vậy là một cách cơ bản nhất, bạn đã có thể gọi mở Flutter module từ Native app. Mặc định sẽ gọi hàm main
trong main.dart
của Flutter module
Nếu bạn muốn truyền thêm arguments từ native sang flutter hoặc bạn mong muốn đổi hàm mặc định, file mặc định mà Native sẽ gọi sang Flutter, bạn tham khảo thêm các sử dụng FlutterEngine
.
Cám ơn và chúc các bạn thành công!
Tham khảo
All rights reserved