在Flutter 开发中混合的形式主要有两种
?
?原生集成 Flutte 混合开发的步骤:
- 创建 Flutter module
- 添加 Flutter module 依赖(为原生项目添加 Flutter 依赖)
- 在 Java/Object-c 中调用 Flutter module
- 编写 Dart 代码
? 运行项目
? 热重启 / 热加载
? 调试代码
? 发布应用
Android:
1. 创建 Flutter module?
首先你得有 原生 android 工程; 路径如下:D:\MineGit\flutter_trip\native_peoject
?首先切换到 原生工程的上一级目录;并且 创建一个flutter模块
C:\Users\user>D:
C:\Users\user>cd D:\MineGit\flutter_trip\native_peoject
D:\MineGit\flutter_trip\native_peoject>cd..
D:\MineGit\flutter_trip>flutter create -t module flutter_module_john
??像这样 flutter? 模块就建好了:
文件结构如下:
?上面就是 flutter_module_john 模块中的文件结构; 你会发现它里面包含 .android 与 .ios,这两个文件夹是 隐藏文件夹(mac 中你必须打开隐藏开关 才能看到文件夹),也是 flutter_module_john 宿主工程:
- .android?? ???????? -> flutter_module_john模块? 的Android 宿主工程
- .ios??????????????????? -> flutter_module_john模块 的 IOS 宿主工程
- lib????????? ? ? ? ? ??? -> flutter_module_john模块 的 Dart 部分的代码
- pubspec.yaml ? -> flutter_module_john模块 项目依赖配置文件
因为宿主工程的存在, 我们这个 flutter_module 在补额外配置的情况下是 可以独立运行 的, 通过安装了 Flutter 与 Dart 插件的 AndroidStudio 打开这个 Flutter_module 项目,通过运行按钮就能直接运行它
能顺利运行到手机上面 就说明这个模块 创建的没问题
2. 添加 Flutter module 依赖
这里我们将 刚刚创建的 Flutter_module 加入到 Android 原生工程中:
1. settings.gradle 首先我们修改项目
setBinding(new Binding([gradle:this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module_john/.android/include_flutter.groovy'
))
就是把 flutter_module 模块添加到 项目中;注意项目路径的写法;得写成你自己的路径;
下面截图中的两行 是编辑器自己给我添加的 可以移除
?检查下 minSdkVersion 版本最低 16(flutter 支持的最低版本)
2.? build.gradle (app)
添加工程依赖
3. 在 Java 中调用 Flutter module
在 Java 中调用 Flutter 模块的两种方式:
- 使用 Flutter.createView? API 方式创建 (作为页面的一部分)
Flutter.createView() 已经被官方弃用 Flutter 1.12版本废弃了io.flutter.facade包导致的;这里使用 FlutterFragment 来创建 FlutterFragment.createDefault(); public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//没有指定路由 传值;只能调到 默认路由(开始界面)
// FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
// fragmentTransaction.add(R.id.someContainer, FlutterFragment.createDefault());
// //fragmentTransaction.replace(R.id.someContainer, FlutterFragment.createDefault());
// fragmentTransaction.commit();
//指定路由并且传值
FlutterFragment flutterFragment = FlutterFragment.withNewEngine()
.initialRoute("{name:'devio',dataList:['aa','bb','bb']}")
.build();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.someContainer, flutterFragment)
.commit();
}
});
}
} 原生传值可以直接 接收到参数: import 'dart:ui' as ui; final String initParams = ui.window.defaultRouteName; ??????? 编辑的时候:编辑原生原生代码只能修改原生的代码;编辑dart 代码; Flutter_module lib 文件夹里面的代码;直接运行 Flutter_module;只能运行 Flutter_module里面的工程;
4. 热重启 /重启加载
大家知道我们在做 Flutter 开发的时候,它自带热 重启/重新加载的功能, 但是你可以能会发现;在混合开发中 Android 项目集成 Flutter 项目的时候 重启/重新加载不起作用了;那在混合开发中怎么启用 重启/重新加载:
- 手机连接我们的 电脑
- 关闭我们的应用;然后 运行 flutter attch;(在对应的 flutter_module 项目根路径)
- 当出现 “Waiting for a connection from Flutter on PACM00... 的时候打开我们原生App;并且进入我们的 Flutter 界面
然后会提示同步信息和 命令信息 (因为我有两个手机连接电脑;这里会有一个选择手机的步骤) D:\MineGit\flutter_trip\flutter_module_john>flutter attach
Multiple devices found:
SM G9650 (mobile) ? 21a9f15c1d037ece ? android-arm64 ? Android 10 (API 29)
PACM00 (mobile) ? JZU8PB9DQOG68D6D ? android-arm64 ? Android 10 (API 29)
[1]: SM G9650 (21a9f15c1d037ece)
[2]: PACM00 (JZU8PB9DQOG68D6D)
Please choose one (To quit, press "q/Q"): 2
Waiting for a connection from Flutter on PACM00...
Syncing files to device PACM00... 7.4s
Flutter run key commands.
r Hot reload.
R Hot restart.
h Repeat this help message.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
Running with sound null safety
?现在你只要 修改完毕 dart 代码保存;然后在 按 r 键就能立马看到效果了
5. 调试 dart 代码
在混合开发模式下, 如何更好的调试我们的代码:
- 关闭App(这一步很关键)
- 点击 AndroidStudio 的 Flutter Attch 按钮(前提是 安装过flutter 与 dart 插件)
- 启动App
打上断点? 就能进入 对应的断点 了
6. 发布应用 配置好证书
signingConfigs {//添加
release {
storeFile file(MYAPP_RELEASE_KEY_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release//添加
}
}
直接运行命令:
>gradlew assembleRelease
或者:
打出来的APK 有:
?在这里可以设置:armeabi-v7a
? 指定 APK 只支持32位 类型 减小包体
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.john.nativetoflutter"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'armeabi-v7a'
// abiFilters "armeabi", "armeabi-v7a", "x86_64", "x86"
}
}
signingConfigs {//添加
release {
storeFile file(MYAPP_RELEASE_KEY_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release//添加
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation project(':flutter')
}
|