#场景#
把一个fluter页面运行到原生App中
#实现步骤#
1:配置
#创建Flutter模块
flutter create -t module flutter_moule
#Android的settings.gradle的配置#
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) ##修改
repositories {
google()
mavenCentral()
maven { url "https://storage.googleapis.com/download.flutter.io" } ##新增的
}
}
include ':app'
setBinding(new Binding([gradle: this])) ##新增的
evaluate(new File(settingsDir.parentFile,'flutter_module/.android/include_flutter.groovy')) ##新增的
#Android的app里的build.gradle配置#
dependencies {
implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
implementation project(':flutter') ##新增的
}
2:编写代码
注意 flutter工程和Android在一个目录下
两种方案:方案 1 最简(推荐,改启动页为 FlutterActivity)、方案 2 原生 Activity 内嵌 FlutterFragment
方案 1:直接把 APP 启动页设为 FlutterActivity【一行搞定,首选】
1、AndroidManifest.xml 修改启动入口
找到原来的启动 Activity,删掉 LAUNCHER 配置,把启动给到 FlutterActivity
xml
<application ...>
<!-- 原生Activity去掉 android.intent.category.LAUNCHER -->
<activity android:name=".MainActivity">
</activity>
<!-- FlutterActivity 设为APP首页,开机直接进Flutter -->
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- 固定初始路由 -->
<meta-data
android:name="io.flutter.embedding.android.FLUTTER_INITIAL_ROUTE"
android:value="/home"/>
</activity>
</application>
android:value="/home"= Dart 接收的初始路由地址
2、Flutter Module main.dart 接收路由
dart
import 'package:flutter/material.dart';
import 'dart:ui';
void main() {
final String initRoute = PlatformDispatcher.instance.defaultRouteName;
runApp(MyApp(initRoute));
}
class MyApp extends StatelessWidget {
final String initRoute;
const MyApp(this.initRoute, {super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: initRoute,
routes: {
'/': (ctx) => const HomePage(),
'/home': (ctx) => const MainFlutterPage()
},
);
}
}
运行 App → 打开直接就是 Flutter 页面。
方案 2:保留原生 MainActivity,onCreate 直接加载 FlutterFragment(原生壳 + Flutter 内容)
1. activity_main.xml 全屏容器
xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_flutter_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
2. MainActivity.java(启动自动加载 Flutter)
java
运行
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import io.flutter.embedding.android.FlutterFragment;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 新建引擎,指定初始路由
FlutterFragment fragment = FlutterFragment.withNewEngine()
.initialRoute("/home")
.build();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.root_flutter_container, fragment)
.commit();
}
}
3. AndroidManifest 保留 MainActivity 为启动项
xml
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
优化:预加载引擎,消除启动白屏(全局 Application 缓存引擎)
MyApplication.java
java
运行
import android.app.Application;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
public class MyApp extends Application {
public static final String FLUTTER_ENGINE_KEY = "cache_engine";
@Override
public void onCreate() {
super.onCreate();
// 预初始化Flutter引擎
FlutterEngine engine = new FlutterEngine(this);
engine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
FlutterEngineCache.getInstance().put(FLUTTER_ENGINE_KEY, engine);
}
}
AndroidManifest 中 application 标签添加:
xml
android:name=".MyApp"
使用缓存引擎(修改 Fragment/Activity 创建代码)
java
运行
// Fragment写法
FlutterFragment fragment = FlutterFragment.withCachedEngine(MyApp.FLUTTER_ENGINE_KEY).build();
// FlutterActivity清单固定缓存引擎
<meta-data
android:name="io.flutter.embedding.android.FLUTTER_ENGINE_ID"
android:value="cache_engine"/>
关键小结
- 最简方案:清单把 FlutterActivity 设置为 LAUNCHER,打开 APP 直接 Flutter 全屏
- 保留原生壳:MainActivity 加载全屏 FlutterFragment
- 预缓存引擎 = 去掉冷启动白屏