如何*确切地*从 Android Java *插件* 平台代码中访问 Flutter 资产?
How *Exactly* to Access Flutter Assets From Within Android Java *Plugin* Platform Code?
我们想要定义一个 Flutter 资产,它可以从同一插件中的 Android 平台代码访问。这方面的文档据称是 here.
请注意,我们不是在讨论 Flutter 应用程序中的自定义平台代码——我们是从插件作者的角度讨论 Flutter 插件代码。
因此,按照文档,我们从位于 [your_plugin_root_dir]\pubspec.yaml 的插件的 pubspec.yaml 文件开始,然后添加资产定义:
assets:
- assets/sound.wav
这指向位于 [your_plugin_root_dir]\assets\sound.wav
的现有文件
到目前为止一切都很好,但是我们遇到了问题:
当您在 Android studio 中创建一个新的 Flutter Plugin 项目时,插件的 Android Java 文件如下所示:
public class PluginTestPlugin implements FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private MethodChannel channel;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "plugin_test");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
}
为了从该代码中访问您的资产,文档建议添加此代码:
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("assets/sound.wav");
AssetFileDescriptor fd = assetManager.openFd(key);
但是由于该代码中不存在“注册商”实例,并且文档没有描述它是如何创建的或如何访问它,所以我迷路了。
我在这里错过了什么????
在方法通道旁边添加另一个字段,以保留绑定;
private MethodChannel channel;
private FlutterPluginBinding binding;
在onAttachedToEngine
中设置:
channel.setMethodCallHandler(this);
binding = flutterPluginBinding;
并在onDetached
中清除
channel.setMethodCallHandler(null);
binding = null;
然后像这样使用它(为此,我向名为 assets/foo.bin
的插件(不是示例应用程序)添加了一个资产,我的插件名称是 plugin1
)
String assetPath = binding
.getFlutterAssets()
.getAssetFilePathBySubpath("assets/foo.bin", "plugin1");
try {
InputStream is = binding.getApplicationContext().getAssets().open(assetPath);
// todo - read the asset into memory or whatever
is.close();
} catch (IOException e) {
Log.e("plugin1", e.getMessage());
}
插件项目的pubspec.yaml需要额外的行来打包资产如下,在plugin
部分之后:
plugin:
platforms:
android:
package: io.swhh.plugin1
pluginClass: Plugin1Plugin
ios:
pluginClass: Plugin1Plugin
assets:
- assets/foo.bin
您可能对 iOS 中的等价物感兴趣(请原谅缺少错误处理)
let key = FlutterDartProject.lookupKey(forAsset: "assets/foo.bin", fromPackage: "plugin1")
let path = Bundle.main.path(forResource: key, ofType: nil, inDirectory: nil)
let url = URL(fileURLWithPath: path!)
// use url to load the resource
我们想要定义一个 Flutter 资产,它可以从同一插件中的 Android 平台代码访问。这方面的文档据称是 here.
请注意,我们不是在讨论 Flutter 应用程序中的自定义平台代码——我们是从插件作者的角度讨论 Flutter 插件代码。
因此,按照文档,我们从位于 [your_plugin_root_dir]\pubspec.yaml 的插件的 pubspec.yaml 文件开始,然后添加资产定义:
assets:
- assets/sound.wav
这指向位于 [your_plugin_root_dir]\assets\sound.wav
的现有文件到目前为止一切都很好,但是我们遇到了问题:
当您在 Android studio 中创建一个新的 Flutter Plugin 项目时,插件的 Android Java 文件如下所示:
public class PluginTestPlugin implements FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private MethodChannel channel;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "plugin_test");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
}
为了从该代码中访问您的资产,文档建议添加此代码:
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("assets/sound.wav");
AssetFileDescriptor fd = assetManager.openFd(key);
但是由于该代码中不存在“注册商”实例,并且文档没有描述它是如何创建的或如何访问它,所以我迷路了。
我在这里错过了什么????
在方法通道旁边添加另一个字段,以保留绑定;
private MethodChannel channel;
private FlutterPluginBinding binding;
在onAttachedToEngine
中设置:
channel.setMethodCallHandler(this);
binding = flutterPluginBinding;
并在onDetached
channel.setMethodCallHandler(null);
binding = null;
然后像这样使用它(为此,我向名为 assets/foo.bin
的插件(不是示例应用程序)添加了一个资产,我的插件名称是 plugin1
)
String assetPath = binding
.getFlutterAssets()
.getAssetFilePathBySubpath("assets/foo.bin", "plugin1");
try {
InputStream is = binding.getApplicationContext().getAssets().open(assetPath);
// todo - read the asset into memory or whatever
is.close();
} catch (IOException e) {
Log.e("plugin1", e.getMessage());
}
插件项目的pubspec.yaml需要额外的行来打包资产如下,在plugin
部分之后:
plugin:
platforms:
android:
package: io.swhh.plugin1
pluginClass: Plugin1Plugin
ios:
pluginClass: Plugin1Plugin
assets:
- assets/foo.bin
您可能对 iOS 中的等价物感兴趣(请原谅缺少错误处理)
let key = FlutterDartProject.lookupKey(forAsset: "assets/foo.bin", fromPackage: "plugin1")
let path = Bundle.main.path(forResource: key, ofType: nil, inDirectory: nil)
let url = URL(fileURLWithPath: path!)
// use url to load the resource