效果图
下载 shadow 项目
为了方便 , 直接使用shadow官方的例子做测试 , 把 shadow 项目 clone 下来并编译
编译成功的shadow 项目如下
可以看到有很多个项目 , 但我们只关注 sample-app , sample-host就行了
编译flutter 项目
这里为了简单 , 使用之前写的futter数独作为测试
我之前写的 flutter 数独源码在这里 flutter_sudoku
项目编译成功后 , 在build/intermediates/flutter文件夹中可以看到如下编译产物
- flutter_assets : 项目资源文件
- libapp.so : 项目文件在这个so里
- libflutter.so : flutter 引擎相关的都在这个so
生成包含flutter的插件apk
把这些flutter 编译产物复制到 sample-app 中
sample-app 依赖flutter 给 Android提供的中间层flutter_embedding sdk
implementation 'io.flutter:flutter_embedding_release:1.0.0-caaafc5604ee9172293eb84a381be6aadd660317'
然后在shadow sample-app 中 添加flutter 测试案例
为了方便起见可以把shadow官方例子中所有的测试案例都注释掉 , 只保留flutter 测试案例 新建一个Activity 继承自FlutterActivity
public class TestFlutterActivity extends FlutterActivity {
public static class Case extends UseCase {
@Override
public String getName() {
return "flutter 插件";
}
@Override
public String getSummary() {
return "测试 flutter 插件";
}
@Override
public Class getPageClass() {
return TestFlutterActivity.class;
}
}
}
点击构建sample-app 项目
会看到sample-app编译成功后会生成两个插件包 , 这两个包含flutter的插件包会提供给sample-host用做动态加载
把这两个插件包复制到宿主的assets 目录下
def createDuplicateApkTask(buildType) {
def apkDir = file("${getBuildDir()}/outputs/apk/plugin/$buildType")
return tasks.create("duplicatePlugin${buildType.capitalize()}ApkTask", Copy) {
group = 'build'
description = "复制一个sample-app-plugin-${buildType}.apk用于测试目的"
from(apkDir) {
include("sample-app-plugin-${buildType}.apk")
rename { "sample-app-plugin-${buildType}2.apk" }
}
into(apkDir)
}.dependsOn(":sample-app:assemblePlugin${buildType.capitalize()}")
}
运行sample-host 项目 , 可以看到一切正常
遇到的问题
使用futter数独作为测试没发现问题 , 但是使用 flutter_wanandroid 做测试的时候, 出现了以下报错
Tried to automatically register plugins with FlutterEngine (io.flutter.embedding.engine.FlutterEngine@449c98d) but could not find or invoke the GeneratedPluginRegistrant.
Caused by: java.lang.ClassNotFoundException: Didn't find class "io.flutter.plugins.GeneratedPluginRegistrant"
GeneratedPluginRegistrant这个类干什么的 ? ,怎么会报找不到这个类GeneratedPluginRegistrant 打开flutter_wanandroid 项目 , 在java/io/flutter/plugins 目录下可以看到GeneratedPluginRegistrant 这个类 , 这个类是flutter为我们自动生成的 , 主要作用是为flutterEngine添加一些给android层做适配的代码
public final class GeneratedPluginRegistrant {
private static final String TAG = "GeneratedPluginRegistrant";
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
try {
flutterEngine.getPlugins().add(new dev.fluttercommunity.plus.connectivity.ConnectivityPlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin connectivity_plus, dev.fluttercommunity.plus.connectivity.ConnectivityPlugin", e);
}
try {
flutterEngine.getPlugins().add(new com.ajinasokan.flutterdisplaymode.DisplayModePlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin flutter_displaymode, com.ajinasokan.flutterdisplaymode.DisplayModePlugin", e);
}
try {
flutterEngine.getPlugins().add(new com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin flutter_inappwebview, com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin", e);
}
try {
flutterEngine.getPlugins().add(new io.github.ponnamkarthik.toast.fluttertoast.FlutterToastPlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin fluttertoast, io.github.ponnamkarthik.toast.fluttertoast.FlutterToastPlugin", e);
}
try {
flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin shared_preferences_android, io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin", e);
}
try {
flutterEngine.getPlugins().add(new com.tekartik.sqflite.SqflitePlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin sqflite, com.tekartik.sqflite.SqflitePlugin", e);
}
}
}
如果flutter想要以插件形式提供给宿主 , GeneratedPluginRegistrant这个类我们肯定没有 , 肯定要自己生成然后添加到flutter插件包中 有没有解决办法 , 当然是有的 , 只不过非常麻烦 ,因为项目中用到的插件 , flutter并没有给我们提供远程依赖的aar , 只能自己把如下图的 android 层 以aar 集成到我们的插件包中 , 然后自己手动生成GeneratedPluginRegistrant , 接着把DisplayModePlugin / ConnectivityPlugin /InAppWebViewFlutterPlugin等插件都添加到flutterEngine中
这个只是种思路 , 待测试