flutter调用android
1,创建flutter消息通道
mFlutter2MethodChannel = new MethodChannel(flutter2Engine.getDartExecutor(), "flutter2/flutter2Java");//字符串的含义跟JsBridge中的js和native互相调用的含义差不多,flutter中要是用这个消息通道时,也要设置为一样的 mFlutter2MethodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call == null || result == null){ if (result!=null){ result.error("-1","MethodCall is null",new Exception("MethodCall is null")); } return; } if ("getJavaMethod".equals(call.method)){ result.success("success "); } else { result.success(" unKnow"); } } });
2,flutter调用native方法
static const platform = const MethodChannel("flutter2/flutter2Java");//跟安卓代码中设置的通道名称字符串一样 Future<Null> _getJavaMethod() async { String str; try { print("dart -_getJavaMethod"); //在通道上调用此方法 final String intValue = await platform.invokeMethod("getJavaMethod");//这个参数是跟安卓协商的,相当于一个变量名,安卓用来筛选flutter需要调用的方法用的 str = 'getJavaMethod $intValue .'; } on Exception catch (e) { str = "Failed to getJavaMethod: '${e.toString()}'."; } setState(() { print("dart -setState"); _counter = str; }); }
调用前:
调用后:
android调用flutter
1,flutter设置回调
Future<dynamic> _platformCallHandler(MethodCall call) async { switch (call.method) { case "getFlutterMethod": return "Flutter name flutter2"; default: return "call.method not getFlutterName"; } } platform.setMethodCallHandler(_platformCallHandler);
2,安卓通过消息通道调用flutter
mFlutter2MethodChannel.invokeMethod("getFlutterMethod", null, new MethodChannel.Result() { @Override public void success(Object result) { if (result != null) { String str = result.toString(); mButton.setText(str); } } @Override public void error(String errorCode, String errorMessage, Object errorDetails) { } @Override public void notImplemented() { } });
调用前:
调用后:
所有代码:
android:
package xyz.djytest.flutter_test_native_project; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; import androidx.appcompat.app.AppCompatActivity; import io.flutter.embedding.android.FlutterView; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngineCache; import io.flutter.embedding.engine.dart.DartExecutor; import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; public class Flutter2Activity extends AppCompatActivity { FlutterEngine mFlutter2Engine; FlutterView mFlutter2View; MethodChannel mFlutter2MethodChannel; Button mButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_flutter2); mButton = findViewById(R.id.button2); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mFlutter2MethodChannel != null) { mFlutter2MethodChannel.invokeMethod("getFlutterMethod", null, new MethodChannel.Result() { @Override public void success(Object result) { if (result != null) { String str = result.toString(); mButton.setText(str); } } @Override public void error(String errorCode, String errorMessage, Object errorDetails) { } @Override public void notImplemented() { } }); } } }); initFlutterEngine(); mFlutter2View = createFlutterView(); mFlutter2View.attachToFlutterEngine(mFlutter2Engine); } private FlutterView createFlutterView() { FlutterView flutterView = new FlutterView(this); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); FrameLayout flContainer = findViewById(R.id.fl_flutter); flContainer.addView(flutterView, lp); flContainer.setVisibility(View.INVISIBLE); FlutterUiDisplayListener listener = new FlutterUiDisplayListener() { @Override public void onFlutterUiDisplayed() { flContainer.setVisibility(View.VISIBLE); } @Override public void onFlutterUiNoLongerDisplayed() { } }; flutterView.addOnFirstFrameRenderedListener(listener); return flutterView; } private void initFlutterEngine() { mFlutter2Engine = FlutterEngineCache.getInstance().get("flutter2"); if (mFlutter2Engine == null) { mFlutter2Engine = new FlutterEngine(this); initChannel(mFlutter2Engine); mFlutter2Engine.getDartExecutor().executeDartEntrypoint( DartExecutor.DartEntrypoint.createDefault() ); FlutterEngineCache.getInstance().put("flutter2", mFlutter2Engine); } } private void initChannel(FlutterEngine flutter2Engine) { mFlutter2MethodChannel = new MethodChannel(flutter2Engine.getDartExecutor(), "flutter2/flutter2Java"); mFlutter2MethodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call == null || result == null) { if (result != null) { result.error("-1", "MethodCall is null", new Exception("MethodCall is null")); } return; } if ("getJavaMethod".equals(call.method)) { result.success("success "); } else { result.success(" unKnow method"); } } }); } @Override protected void onResume() { super.onResume(); mFlutter2Engine.getLifecycleChannel().appIsResumed(); } @Override protected void onStart() { super.onStart(); } @Override protected void onRestart() { super.onRestart(); } @Override protected void onPause() { super.onPause(); mFlutter2Engine.getLifecycleChannel().appIsInactive(); } @Override protected void onStop() { super.onStop(); mFlutter2Engine.getLifecycleChannel().appIsPaused(); } @Override protected void onDestroy() { super.onDestroy(); FlutterEngineCache.getInstance().remove("flutter2"); mFlutter2View = null; } }
flutter:
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( // This is the theme of your application. // // Try running your application with "flutter run". You'll see the // application has a blue toolbar. Then, without quitting the app, try // changing the primarySwatch below to Colors.green and then invoke // "hot reload" (press "r" in the console where you ran "flutter run", // or press Run > Flutter Hot Reload in a Flutter IDE). Notice that the // counter didn't reset back to zero; the application is not restarted. primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect // how it looks. // This class is the configuration for the state. It holds the values (in this // case the title) provided by the parent (in this case the App widget) and // used by the build method of the State. Fields in a Widget subclass are // always marked "final". final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { String _counter = "default is null"; int i = 0; void _incrementCounter() { setState(() { // This call to setState tells the Flutter framework that something has // changed in this State, which causes it to rerun the build method below // so that the display can reflect the updated values. If we changed // _counter without calling setState(), then the build method would not be // called again, and so nothing would appear to happen. if (_counter == "default is null") { _counter = i.toString(); } else { _counter += i.toString(); } i++; }); } static const platform = const MethodChannel("flutter2/flutter2Java"); Future<Null> _getJavaMethod() async { String str; try { print("dart -_getJavaMethod"); // 在通道上调用此方法 final String intValue = await platform.invokeMethod("getJavaMethod"); str = 'getJavaMethod $intValue .'; } on Exception catch (e) { str = "Failed to getJavaMethod: '${e.toString()}'."; } setState(() { print("dart -setState"); _counter = str; }); } Future<dynamic> _platformCallHandler(MethodCall call) async { switch (call.method) { case "getFlutterMethod": return "Flutter name flutter2"; default: return "call.method not getFlutterName"; } } @override Widget build(BuildContext context) { platform.setMethodCallHandler(_platformCallHandler); // This method is rerun every time setState is called, for instance as done // by the _incrementCounter method above. // // The Flutter framework has been optimized to make rerunning build methods // fast, so that you can just rebuild anything that needs updating rather // than having to individually change instances of widgets. 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: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. child: Column( // Column is also a layout widget. It takes a list of children and // arranges them vertically. By default, it sizes itself to fit its // children horizontally, and tries to be as tall as its parent. // // Invoke "debug painting" (press "p" in the console, choose the // "Toggle Debug Paint" action from the Flutter Inspector in Android // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) // to see the wireframe for each widget. // // Column has various properties to control how it sizes itself and // how it positions its children. Here we use mainAxisAlignment to // center the children vertically; the main axis here is the vertical // axis because Columns are vertical (the cross axis would be // horizontal). mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), floatingActionButton: FloatingActionButton( // onPressed: _incrementCounter, onPressed: _getJavaMethod, tooltip: 'Increment', child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } }