一、简介
此文章主要记录本人的flutter插件开发过程以及遇到的问题等,如有错误请指正.
二、开发准备(Windows)
1.Android Studio 4.0以上
2.Flutter SDK
三、环境配置
1.安装flutter sdk
下载好之后,解压,找到根目录下的flutter文件下找到flutter_console.bat,双击运行并启动flutter命令行。
2.更新环境变量
要在终端运行 flutter 命令, 你需要添加以下环境变量到系统PATH:
转到 “控制面板>用户帐户>用户帐户>更改我的环境变量”
在“用户变量”下检查是否有名为“Path”的条目:
如果该条目存在, 追加 flutter\bin的全路径,使用 ; 作为分隔符.
如果条目不存在, 创建一个新用户变量 Path ,然后将 flutter\bin的全路径作为它的值.
在“用户变量”下检查是否有名为”PUB_HOSTED_URL”和”FLUTTER_STORAGE_BASE_URL”的条目,如果没有,也添加它们。
重启Windows以应用此更改
3.测试flutter环境
打开命令行输入:flutter doctor
如图可以看到有两个报错为插件工具没有导入可查看这里解决问题:
https://www.jianshu.com/p/3dc7dbd0712c
四、插件开发
1.使用Android Studio创建flutter插件
参照: https://www.jianshu.com/p/3dc7dbd0712c
2.编译插件桥接类
找到插件桥接类
打开后可以看到很多红色报错,如下图可以点开新的AS界面进行编译:
3.方法简介
onAttachedToEngine方法
初始化方法,"flutter_vin_plugin"为定义好的插件桥接类名,后面调用需要一一对应。
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_vin_plugin");
channel.setMethodCallHandler(this);
}
onMethodCall方法
接受从js层获取参数的方法"isCropImage"等都是传递的参数标识通过MethodCall 对象获取传递过来的数据
startScanVin等为自定义的原生方法,里面可以自定义一些操作
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
resultPlugin = result;
String isCrop = call.argument("isCropImage");
ConstantConfig.isImportCrop = !TextUtils.isEmpty(isCrop) && isCrop.equals("1");
ConstantConfig.isCheckMotorbike = Boolean.getBoolean(call.argument("containMoto") + "");
initOcrFile();
if (call.method.equals("scanVin")) {
startScanVin();
} else if (call.method.equals("imageVin")) {
startImport();
} else {
unInitOcrApi();
result.notImplemented();
}
}
onAttachedToActivity方法
此方法的包含一些原生的activity中的一些监听方法,添加监听后可实现对应的原生方法。
①addRequestPermissionsResultListener: 对应原生中的权限监听方法
②addActivityResultListener:对应原生中activity回调方法等一些有关activity生命周期的方法
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
this.activity = binding.getActivity();
binding.addRequestPermissionsResultListener(new PluginRegistry.RequestPermissionsResultListener() {
@Override
public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case SCAN_PERMISSION_CODE:
if (permissions.length != 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {//失败
Toast.makeText(activity, "请允许权限在识别", Toast.LENGTH_SHORT).show();
} else {//成功
//启动启动VIN码扫描识别页面
Intent intent = new Intent(activity, ScanVinActivity.class);
activity.startActivityForResult(intent, VIN_RECOG_CODE);
}
break;
case IMPORT_PERMISSION_CODE:
if (permissions.length != 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {//失败
Toast.makeText(activity, "请允许权限在识别", Toast.LENGTH_SHORT).show();
} else {//成功
//启动启动VIN码导入识别页面
Intent intent = new Intent(activity, VinRecogActivity.class);
activity.startActivityForResult(intent, VIN_RECOG_CODE);
}
break;
}
return false;
}
});
binding.addActivityResultListener(new PluginRegistry.ActivityResultListener() {
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null && requestCode == VIN_RECOG_CODE) {
//接收所有识别结果,图片
String vinResult = data.getStringExtra("vinResult");
//接收识别结果的状态码,0表示成功,其他值表示识别失败
int recogCode = data.getIntExtra("recogCode", -1);
String vinThumbPath = data.getStringExtra("vinThumbPath");
String vinAreaPath = data.getStringExtra("vinAreaPath");
Map<String, String> map = new HashMap<>();
map.put("ocrResult", vinResult);
map.put("ocrThumbPath", vinThumbPath);
map.put("ocrAreaPath", vinAreaPath);
resultPlugin.success(map);
}
return false;
}
});
}
到此插件部分已经开发的差不多了
五、引用插件
1.在插件中的demo调用测试
找到插件目录下的lib文件夹下的文件打开如下;
此文件为插件原生与js端沟通的桥梁所有的方法交互都需要通过此方法
如下图,一共定义几个方法,比如licName等参数是js传递过来的参数,将这些参数放入param中,通过我们上面定义的flutter_vin_plugin的对象_channel执行invokeMethod方法调用原生并声明原生中的方法名scanVin以及传递js端数据集合param,,通过map接受原生中返回的数据即可.
找到js端主页
打开后可以定义我们在桥接中定义好的方法名称
下面在main.dart中定义对应调用的方法:
result为从原生获取的数据_resultOcr为定义好的变量.
Future<void> scanVin() async {
Map<String, String> result;
// 参数说明 ("授权文件名称","是否屏蔽部分校验规则") 0为false 1为true
result = await FlutterVinPlugin.scanVin("7332DBAFD2FD18301EF6", "0"); // TODO 扫描识别
setState(() {
_resultMap = result;
_resultOcr = _resultMap['ocrResult'];
_resultThumbPath = _resultMap['ocrThumbPath'];
_resultAreaPath = _resultMap['ocrAreaPath'];
});
}
然后即可在view中点击监听调用:
main.dart中这里不多做描述了,具体可以查看官方文档学习如何开发。
2.在实际项目中调用测试
①将插件复制进Flutter项目目录中
②Flutter项目中的pubspec.yaml文件,进行如下图配置,path根据自己的插件的相对路径配置
③在你的项目中打开pubspec.yam文件执行插件引用如图:
④在你的项目中打开example下GeneratedPluginRegistrant.Java代码,可以看到这里已经成功引用了FlutterVinPlugin插件如图
六、调试运行
运行成功