如何在Flutter工程中添加Android AAR文件

时间:2022-06-11 10:06:46

为了方便Android和iOS移动开发,Google推出了Flutter。Flutter和Xamarin,Cordova的概念相似 - 使用一种编程语言为多个平台开发。Flutter使用Dart。不过当使用第三方SDK的时候,Flutter依然需要用到Java或者Objective-C来写后台代码。

添加Android AAR

下载Flutter源码

选择一个aar文件,我这里用DynamsoftBarcodeReader.aar

把目录flutter/examples/hello_services/android/导入到Android Studio中。

点击File > New > New Module,选择Import .JAR/.AAR Package,添加AAR文件。打开工程属性,添加依赖模块就可以了。

如何在Flutter工程中添加Android AAR文件

Flutter UI与Java后台

打开AndroidManifest.xml 添加权限。

使用Java代码调用aar中的接口,然后把结果通过消息的形式发送到Flutter UI。

private String onGetBarcode(String json) {
String filename;
try {
JSONObject message = new JSONObject(json);
filename = message.getString("filename");
} catch (JSONException e) {
Log.e(TAG, "JSON exception", e);
return null;
}

String locationProvider;
String barcodeResult = "No barcode detected";
File file = new File(filename);
if (!file.exists()) {
barcodeResult = "No file exists: " + file.toString();
Toast.makeText(BarcodeReaderActivity.this, barcodeResult, Toast.LENGTH_LONG).show();

return null;
}
else {
Bitmap bitmap = BitmapFactory.decodeFile(file.toString());
BarcodeReader reader = new BarcodeReader("license");
ReadResult result = reader.readSingle(bitmap, Barcode.QR_CODE);
Barcode[] all = result.barcodes;
if (all != null && all.length == 1) {
barcodeResult = all[0].displayValue;
}
else {
barcodeResult = "no barcode found: " + file.toString();
}

bitmap.recycle();

}

JSONObject reply = new JSONObject();
try {
if (barcodeResult != null) {
reply.put("result", barcodeResult);
} else {
reply.put("result", "No barcode detected");
}
} catch (JSONException e) {
Log.e(TAG, "JSON exception", e);
return null;
}

return reply.toString();
}

创建Flutter Input, Button以及Text widgets:

@override
Widget build(BuildContext context)
{
if (_isExisted) {
return new Material(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Text('Barcode Reader'),
new Input(
labelText: 'Please input the image path',
value: new InputValue(text: _filename),
onChanged: onTextChanged,
autofocus: true,
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new RaisedButton(
child: new Text('Read'),
onPressed: _getBarcode
),
new RaisedButton(
child: new Text('Reset'),
onPressed: _resetResult
),
]
),
new Image.file(new File(_filename)),
new Text('$_result'),
]
)
)
);
}
else {
return new Material(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Text('Barcode Reader'),
new Input(
labelText: 'Please input the image path',
onChanged: onTextChanged,
autofocus: true,
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new RaisedButton(
child: new Text('Read'),
onPressed: _getBarcode
),
new RaisedButton(
child: new Text('Reset'),
onPressed: _resetResult
),
]
),
new Text('$_result'),
]
)
)
);
}
}

Future<Null> _readBarcode() async {
final Map<String, String> message = <String, String>{'filename':_filename};
final Map<String, dynamic> reply = await HostMessages.sendJSON('getBarcode', message);
// If the widget was removed from the tree while the message was in flight,
// we want to discard the reply rather than calling setState to update our
// non-existent appearance.
if (!mounted)
return;
setState(() {
_result = reply['result'].toString();
});
}

运行程序:

如何在Flutter工程中添加Android AAR文件

参考资料

安装包问题

Flutter工程编译之后,会把libsky_shell.so打包到APK的armeabi-v7a目录中。我使用的aar文件还包含了arm64-v8a,编译之后会发现arm64-v8a目录中没有libsky_shell.so。这个时候如果APK安装到64位CPU的安卓设备上,会因为找不到libsky_shell.so导致程序崩溃无法启动。

如何在Flutter工程中添加Android AAR文件

如何在Flutter工程中添加Android AAR文件

解决的方法就是只保留armeabi-v7a的动态连接库,其余都删掉。

源码

https://github.com/yushulx/flutter-android-aar