为了方便Android和iOS移动开发,Google推出了Flutter。Flutter和Xamarin,Cordova的概念相似 - 使用一种编程语言为多个平台开发。Flutter使用Dart。不过当使用第三方SDK的时候,Flutter依然需要用到Java或者Objective-C来写后台代码。
添加Android AAR
下载。
选择一个aar文件,我这里用。
把目录flutter/examples/hello_services/android/导入到Android Studio中。
点击File > New > New Module,选择Import .JAR/.AAR Package,添加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:[ 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: [ 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: [ new Text('Barcode Reader'), new Input( labelText: 'Please input the image path', onChanged: onTextChanged, autofocus: true, ), new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ new RaisedButton( child: new Text('Read'), onPressed: _getBarcode ), new RaisedButton( child: new Text('Reset'), onPressed: _resetResult ), ] ), new Text('$_result'), ] ) ) ); } } Future _readBarcode() async { final Map message = {'filename':_filename}; final Map 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工程编译之后,会把libsky_shell.so打包到APK的armeabi-v7a目录中。我使用的aar文件还包含了arm64-v8a,编译之后会发现arm64-v8a目录中没有libsky_shell.so。这个时候如果APK安装到64位CPU的安卓设备上,会因为找不到libsky_shell.so导致程序崩溃无法启动。
解决的方法就是只保留armeabi-v7a的动态连接库,其余都删掉。
源码