background
Flutter is currently one of the most popular UI frameworks for mobile platforms (I understand it is just a framework) and some features inevitably invoke native features such as camera, fingerprint authentication and other underlying features. This tutorial will focus on how Flutter communicates with native Android.
1. Write the flutter public page
Two-way data communication mainly has the following steps: (1) Sending channel definition:
static const receive = const EventChannel('com.gxx.receive/plugin'); Future<Null> _statrtToNativeActivity() async {String result = await sendToNative.invokeMethod('startToEditActivity'); } Future<Null> _sendDataToNative() async {Map<String, String> Map = {"flutter": "I was transmitted by flutter"}; String result = await sendToNative.invokeMethod('mapData', map); print(result); }Copy the code
(2) Definition of receiving channel:
Static const receiveFromNative =const EventChannel('com.gxx.send/plugin'); StreamSubscription _streamSubscription;Copy the code
(3) Instantiate the data receive listener in the initState() method
@override void initState() { super.initState(); // Start listening, Pass data to the Flutter interface via the native interface if (_streamSubscription == null) {_streamSubscription = receiveFromNative.receiveBroadcastStream().listen((event) { setState(() { _currentCount = event; print("ChannelPage: $event"); }); }, onError: (Object error) {setState(() {_currentCount = "timer exception "; print(error); }); }); }}Copy the code
(4) Fetch the message subscription channel from the Dispose () method
@override void dispose() { // TODO: implement dispose super.dispose(); If (_streamSubscription! = null) { _streamSubscription.cancel(); }}Copy the code
(6) The complete code is as follows:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( // Here we take the value from the MyHomePage object that was created by // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: TestWidget()); } } class TestWidget extends StatefulWidget { @override State<StatefulWidget> createState() { return TestState(); }} class TestState extends State<TestWidget> {static const sendToNative = const MethodChannel('com.gxx.receive/plugin'); Future<Null> _statrtToNativeActivity() async {String result = await sendToNative.invokeMethod('startToEditActivity'); print(result); Future<Null> _sendDataToNative() async {Map<String, String> Map = {"flutter": "I am passed over "}; String result = await sendToNative.invokeMethod('mapData', map); print(result); Static const receiveFromNative = const EventChannel('com.gxx.send/plugin'); StreamSubscription _streamSubscription; var _currentCount; @override void initState() { super.initState(); If (_streamSubscription == null) {_streamSubscription = receiveFromNative.receiveBroadcastStream().listen((event) { setState(() { _currentCount = event; print("ChannelPage: $event"); }); }, onError: (Object error) {setState(() {_currentCount = "timer exception "; print(error); }); }); } } @override Widget build(BuildContext context) { // TODO: implement build return Container( child: Column( children: <Widget>[RaisedButton(child: Text(' jump to native '), onPressed: (){_statrtToNativeActivity();},), RaisedButton(child: Text(' let the native receive the data '), onPressed: (){_sendDataToNative();},), RaisedButton(child: The Text (" native passed data: $_currentCount "), onPressed: () {},),),); } @override void dispose() { // TODO: implement dispose super.dispose(); If (_streamSubscription! = null) { _streamSubscription.cancel(); }}}Copy the code
2. Native code writing
(1) Define data receiving plugins (from Flutter to native interface)
Public class FlutterPluginFtoA implements MethodChannel. MethodCallHandler {/ / here to use the same attention and Flutter public static final String A_TO_F_CHANNEL = "com.gxx.receive/plugin"; private Activity handlerActivity; public FlutterPluginFtoA(Activity activity) { this.handlerActivity = activity; } public static void registerWith(PluginRegistry.Registrar) {// Main method MethodChannel MethodChannel MethodChannel = new MethodChannel(registrar.messenger(), A_TO_F_CHANNEL); FlutterPluginFtoA instance = new FlutterPluginFtoA(registrar.activity()); methodChannel.setMethodCallHandler(instance); } @Override public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { switch (methodCall.method){ case "showToast": Object arguments = methodCall.arguments; MakeText (handlerActivity, "received Flutter" + arguments, totoast.LENGTH_SHORT). Show (); break; Case "startToEditActivity": Intent editActivityIntent = New Intent(handlerActivity, testActivity.class); handlerActivity.startActivity(editActivityIntent); result.success("startOk"); break; String text = methodCall.argument(" Flutter "); String text = methodCall.argument(" Flutter "); Toast.maketext (handlerActivity, "receive:" + text, toast.length_short).show(); break; }}}Copy the code
(2) Define data transfer from the native end to the Flutter end
public class FlutterPluginAtoF implements EventChannel.StreamHandler { public static final String F_TO_A_CHANNEL = "com.gxx.send/plugin"; private static FlutterPluginAtoF instance; private EventChannel.EventSink events; public static FlutterPluginAtoF getInstance(){ return instance; } @Override public void onListen(Object o, EventChannel.EventSink eventSink) { this.events=eventSink; } public static void registerWith(PluginRegistry.Registrar registrar){ EventChannel eventChannel=new EventChannel(registrar.messenger(),F_TO_A_CHANNEL); instance=new FlutterPluginAtoF(); eventChannel.setStreamHandler(instance); } @Override public void onCancel(Object o) { } public void sendEventData(Object data){ if(events! =null){ events.success(data); }}}Copy the code
(3) Register the receiver and sender plug-ins in MainActivity
class MainActivity : FlutterActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState) // setContentView(R.layout.activity_edit_h5) // Get its own Registry val Registry = flutterView.pluginRegistry; / / registered plug-in FlutterPluginFtoA. RegisterWith (registry. RegistrarFor (FlutterPluginFtoA. A_TO_F_CHANNEL)); FlutterPluginAtoF.registerWith(registry.registrarFor(FlutterPluginAtoF.F_TO_A_CHANNEL)); }}Copy the code
(4) Jump directly to the native interface on the Flutter page and click ok to transfer the native data to the Flutter page
public class TestActivity extends Activity implements View.OnClickListener { private int currentCount = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_edit_h5); Button btn=findViewById(R.id.tvIntentTxt); Btn.settext (" transmitted to flutter"); btn.setOnClickListener(this); } @Override public void onClick(View view) { // FlutterPluginAtoF.getInstance().sendEventData(""+ currentCount++); MakeText (this, currentCount+"", toasts.LENGTH_SHORT).show(); }}Copy the code
Effect of 3.
Description: This is the native interface transferred to the Flutter interface
Description: The above is transmitted from the Flutter interface to the native interface
4. The last
This blog is just for learning record knowledge, thanks to other blogs for providing ideas. Source address :github.com/guoxuxiong/…