1. Android プロジェクトの統合 Flutter モジュール プロジェクト:
1. 次のコマンドを使用して、Flutter モジュール プロジェクト lib_flutter (Android プロジェクトと同じレベルのディレクトリに属します) を作成します。
flutter create -t module --org com.yyh lib_flutter
2. Android プロジェクト構成を更新します。
(1) Android プロジェクトの Support V4/V7 パッケージを AndroidX パッケージに置き換えます。プロジェクトを右クリックし、ポップアップ メニューで [リファクタリング] > [AndroidX に移行...] を選択し、表示されるボックスで [リファクタリングを行う] をクリックします。左下隅にある をクリックし、自動で置き換えが完了するまで待ちます。
(2) Android project/app/build.gradle で、compileSdkVersion と targetSdkVersion を 31 に変更します。
android {
compileSdkVersion 31 //修改为31,否则报错
buildToolsVersion '30.0.2'
defaultConfig {
minSdkVersion 23
targetSdkVersion 31 //修改为31,否则报错
//...省略其他配置
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
(3) Android project/build.gradle の kotlin_version を変更します。
buildscript {
ext.kotlin_version = '1.6.10'
...
dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
}
}
(4) AndroidManifest.xml で Android12 エラー報告を処理します。
<application tools:node="replace"> <!-- 替换三方库中的相关属性,以此处为准 -->
<activity android:exported="true"> <!-- 为含<intent-filter>的节点增加android:exported属性(Android12要求) -->
<intent-filter>...</intent-filter>
</activity>
<receiver android:exported="true">
<intent-filter>...</intent-filter>
</receiver>
<service android:exported="true">
<intent-filter>...</intent-filter>
</service>
</application>
3. Flutter モジュールをインポートします。
(1) lib_flutter モジュール プロジェクトをロードし、Android プロジェクト/settings.gradle に追加します。
... #省略其他配置
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir.parentFile, 'lib_flutter/.android/include_flutter.groovy'))
#以下2行Sync后自动产生,无需添加(如果不能生成,则手动添加)
include ':lib_flutter'
project(':lib_flutter').projectDir = new File('../lib_flutter')
(3) Android project/app/build.gradle に Flutter 依存関係を追加します。
dependencies {
//...省略其他配置
implementation project(':flutter') //添加Flutter依赖
}
(4) [Sync Project With...] をクリックして同期すると、完了後に Android Studio で lib_flutter モジュールが表示されます。
4. Flutter ページに移動します。
(1) AndroidManifest.xml の <application> ノードに FlutterActivity を追加します。
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:theme="@style/FlutterPageTheme"
android:hardwareAccelerated="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"
/>
(2) Flutter エントリのホームページにジャンプします (コールド スタート):
startActivity(FlutterActivity.createDefaultIntent(this));
(3) Flutter カスタム ページにジャンプします。
方法 1 (コールド スタート):
startActivity(FlutterActivity.withNewEngine()
.initialRoute("路由id") //要跳转的页面路由id,需要在Flutter中注册此路由id
//.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent) //设置透明背景
.build(this));
方法 2 (ホットスタート):
//初始化FlutterEngine
public class AFApplication extends Application {
public FlutterEngine mFlutterEngine; //预热方式启动的FlutterEngine
@Override
public void onCreate() {
super.onCreate();
initFlutterEngine();
...
}
void initFlutterEngine(){//初始化FlutterEngine
mFlutterEngine = new FlutterEngine(this);
mFlutterEngine.getNavigationChannel().setInitialRoute("路由id"); //设置初始跳转页路由id,需要在Flutter中注册此路由id
mFlutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault()); //开始预热FlutterEngine
FlutterEngineCache.getInstance().put("engine_id", mFlutterEngine); //缓存engine_id
}
}
//跳转Flutter指定页(热启动,低延迟)
startActivity(FlutterActivity.withCachedEngine("engine_id") //使用已缓存的engine_id启动Flutter自定义页
//.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent) //设置透明背景
.build(this));
5. Flutter Fragment と Flutter View の公式ドキュメントを参照してください。
https://flutter.cn/docs/development/add-to-app/android/add-flutter-fragment
2. iOS プロジェクトの統合 Flutter モジュール プロジェクト:
1. 次のコマンドを使用して、Flutter モジュール プロジェクト lib_flutter (iOS プロジェクトと同じレベルのディレクトリに属します) を作成します。
flutter create --template module lib_flutter
2. iOS プロジェクトを構成し、プロジェクト/Podfile に追加します (完了後にコマンドを実行します: pod install)。
#导入lib_flutter模块工程
flutter_application_path = '../lib_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'iOSP_FlutterM' do
use_frameworks!
install_all_flutter_pods(flutter_application_path) #flutter相关
end
#flutter相关
post_install do |installer|
flutter_post_install(installer) if defined?(flutter_post_install)
end
3. Flutter ページに移動します。
(1) モード 1 (コールド スタート):
- (void)startFlutterPageByCold{
//跳转Flutter入口首页
FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
//跳转Flutter指定页,路由id需要在Flutter中注册
//FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithProject:nil initialRoute:@"路由id" nibName:nil bundle:nil];
[self presentViewController:flutterViewController animated:YES completion:nil];
}
(2) モード 2 (ホットスタート):
AppDelegate.h:
@import Flutter;
//...省略其他无关的
@interface AppDelegate : FlutterAppDelegate
@property (nonatomic,strong) FlutterEngine *flutterEngine; //定义FlutterEngine
//...省略其他无关的
@end
AppDelegate.m:
#import "AppDelegate.h"
#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h>
//...省略其他无关的
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.flutterEngine = [[FlutterEngine alloc] initWithName:@"engine_id"];
[self.flutterEngine run]; //跳转Flutter入口首页
//[self.flutterEngine runWithEntrypoint:FlutterDefaultDartEntrypoint initialRoute:@"路由id"]; //跳转Flutter指定页面,路由id需要在Flutter中注册
[GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine]; //连接插件(仅带有iOS平台的插件时需要)
return YES;
}
//...省略其他无关的
ジャンプコード:
- (void)startFlutterPageByHot{
FlutterEngine *flutterEngine = ((AppDelegate *)UIApplication.sharedApplication.delegate).flutterEngine;//获取AppDelegate中的FlutterEngine
FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
[self presentViewController:flutterViewController animated:YES completion:nil];
}