Flutter Native for android
Android 中的 原生和 Flutter 通信:原生跳转 Flutter 的几种方式:Flutter 调用 原生 & 原生 调用Flutter原生跳转 Flutter 几种方式 (该方式不能相互调用):不适用于原生和Flutter的通信; 仅仅是原生 中打开Flutter第一种方法:缓存的方式打开FlutterEngine , 需要Application配合;缺点不能直接传参;优点二次
·
Android 中的 原生和 Flutter 通信:
- 原生跳转 Flutter 的几种方式:
- Flutter 调用 原生 & 原生 调用Flutter
原生跳转 Flutter 几种方式 (该方式 不适用相互调用):
不适用于原生和Flutter的通信; 仅仅是原生 中打开Flutter
第一种方法:缓存的方式打开FlutterEngine , 需要Application配合;缺点不能直接传参;优点二次打开很快;已经缓存过了;同一个实例
//缓存的方式 打开FlutterEngine缺点不能直接传参; 依赖 MyAppcation startActivity( FlutterActivity .withCachedEngine(MyApplicaiton.CACHED_ENGINE_ID) .build(MainActivity.this) );MyApplication:
package com.john.nativetoflutter; import android.app.Application; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngineCache; import io.flutter.embedding.engine.dart.DartExecutor; public class MyApplicaiton extends Application { public static final String CACHED_ENGINE_ID = "MY_CACHED_ENGINE_ID"; @Override public void onCreate() { super.onCreate(); //在MyApplication中预先初始化Flutter引擎以提升Flutter页面打开速度 FlutterEngine flutterEngine = new FlutterEngine(this); // Start executing Dart code to pre-warm the FlutterEngine. flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault()); // Cache the FlutterEngine to be used by FlutterActivity. FlutterEngineCache.getInstance().put(CACHED_ENGINE_ID, flutterEngine); } }第二种:不缓存直接打开 不依赖 Applicaiton;有点可以传参数,每次都是新的实例;缺点多次打开 慢;
//不不緩存 直接打開;每次都是新的 實例;有點可疑傳參 startActivity( FlutterActivity .withNewEngine() .initialRoute("{name:'devio',dataList:['aa','bb','bb']}")//传递的参数 .build(MainActivity.this) );第三中: 和第二种类似:不缓存 不传参;不需要依赖 Applicaiton
startActivity( FlutterAppActivity.createDefaultIntent(MainActivity.this));
Flutter 原生的相互调用 :
重写 FlutterActivity: FlutterAppActivity;
package com.john.nativetoflutter.channelPlugins; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.widget.Button; import android.widget.LinearLayout; import androidx.annotation.NonNull; import io.flutter.embedding.android.FlutterActivity; public class FlutterAppActivity extends FlutterActivity { private static final String TAG = FlutterAppActivity.class.getSimpleName(); public final static String INIT_PARAMS = "initParams"; private BasicMessageChannelPlugin basicMessageChannelPlugin; private EventChannelPlugin eventChannelPlugin; private String initParams; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(getIntent().hasExtra(FlutterAppActivity.INIT_PARAMS)){ initParams = getIntent().getStringExtra(INIT_PARAMS); } if (getFlutterEngine() != null) { //注册Flutter plugin eventChannelPlugin = EventChannelPlugin.registerWith(getFlutterEngine().getDartExecutor()); MethodChannelPlugin.registerWith(getFlutterEngine().getDartExecutor(), this); basicMessageChannelPlugin = BasicMessageChannelPlugin.registerWith(getFlutterEngine().getDartExecutor(), this); } else { Log.e(TAG, "getFlutterEngine() is null register plugin fail"); } } /** * 重载该方法来传递初始化参数 * * @return */ @NonNull @Override public String getInitialRoute() { return initParams == null ? super.getInitialRoute() : initParams; } //主動條用eventChannelPlugin void sendMessageEventChannel(String message){ eventChannelPlugin.send(message); } //basicMessageChannel void sendMessageBasicMessageChannel(String message){//回調 basicMessageChannelPlugin.send(message, this::onShowMessage); } private void onShowMessage(String s) { System.out.println("-----onShowMessage"+s); } }添加:
BasicMessageChannel BasicMessageChannelPlugin.javapackage com.john.nativetoflutter.channelPlugins; import android.app.Activity; import android.widget.Toast; import androidx.annotation.Nullable; import io.flutter.plugin.common.BasicMessageChannel; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.StringCodec; /** * BasicMessageChannel * 用于传递字符串和半结构化的信息,持续通信,如:Native将遍历到的文件信息陆续传递到Dart * ,在比如:Flutter将从服务端陆陆续获取到信息交个Native加工,Native处理完返回等 */ public class BasicMessageChannelPlugin implements BasicMessageChannel.MessageHandler<String>, BasicMessageChannel.Reply<String> { private final Activity activity; private final BasicMessageChannel<String> messageChannel; static BasicMessageChannelPlugin registerWith(BinaryMessenger messenger, Activity activity) { return new BasicMessageChannelPlugin(messenger, activity); } private BasicMessageChannelPlugin(BinaryMessenger messenger, Activity activity) { this.activity = activity; this.messageChannel = new BasicMessageChannel<>(messenger, "BasicMessageChannelPlugin", StringCodec.INSTANCE); //设置消息处理器,处理来自Dart的消息 messageChannel.setMessageHandler(this); } @Override public void onMessage(String str, BasicMessageChannel.Reply<String> reply) {//处理Dart发来的消息 reply.reply("BasicMessageChannel收到:" + str);//可以通过reply进行回复 // if (activity instanceof IShowMessage) { // ((IShowMessage) activity).onShowMessage(s); // } Toast.makeText(activity, str, Toast.LENGTH_SHORT).show(); } /** * 向Dart发送消息,并接受Dart的反馈 * * @param message 要给Dart发送的消息内容 * @param callback 来自Dart的反馈 */ void send(String message, BasicMessageChannel.Reply<String> callback) { messageChannel.send(message, callback); } @Override public void reply(String s) { } }EventChannel EventChannelPlugin.javapackage com.john.nativetoflutter.channelPlugins; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.EventChannel; /** * EventChannelPlugin * 用于数据流(event streams)的通信,持续通信,通过长用于Native向Dart的通信, * 如:手机电量变化,网络连接变化,陀螺仪,传感器等; */ public class EventChannelPlugin implements EventChannel.StreamHandler { private EventChannel.EventSink eventSink; static EventChannelPlugin registerWith(BinaryMessenger messenger) { EventChannelPlugin plugin = new EventChannelPlugin(); new EventChannel(messenger, "EventChannelPlugin").setStreamHandler(plugin); return plugin; } void send(Object params) { if (eventSink != null) { eventSink.success(params); } } @Override public void onListen(Object args, EventChannel.EventSink eventSink) { this.eventSink = eventSink; } @Override public void onCancel(Object o) { eventSink = null; } }MethodChannel MethodChannelPlugin.javapackage com.john.nativetoflutter.channelPlugins; import android.app.Activity; import android.widget.Toast; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; /** * MethodChannelPlugin * 用于传递方法调用(method invocation),一次性通信,通常用于Dart调用Native的方法:如拍照; */ public class MethodChannelPlugin implements MethodCallHandler { private final Activity activity; /** * Plugin registration. */ public static void registerWith(BinaryMessenger messenger, Activity activity) { MethodChannel channel = new MethodChannel(messenger, "MethodChannelPlugin"); MethodChannelPlugin instance = new MethodChannelPlugin(activity); channel.setMethodCallHandler(instance); } private MethodChannelPlugin(Activity activity) { this.activity = activity; } @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { switch (call.method) {//处理来自Dart的方法调用 case "send": showMessage(call.arguments()); result.success("MethodChannelPlugin收到:" + call.arguments);//返回结果给Dart break; default: result.notImplemented(); } } /** * 展示来自Dart的数据 * * @param arguments */ private void showMessage(String arguments) { // if (activity instanceof IShowMessage) { // ((IShowMessage) activity).onShowMessage(arguments); // } Toast.makeText(activity, arguments, Toast.LENGTH_SHORT).show(); } }MainActivity.javapackage com.john.nativetoflutter; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentTransaction; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.EditText; import com.john.nativetoflutter.channelPlugins.BasicMessageChannelPlugin; import com.john.nativetoflutter.channelPlugins.EventChannelPlugin; import com.john.nativetoflutter.channelPlugins.FlutterAppActivity; import java.security.DomainCombiner; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.android.FlutterFragment; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngineCache; import io.flutter.embedding.engine.dart.DartExecutor; public class MainActivity extends AppCompatActivity { private BasicMessageChannelPlugin basicMessageChannelPlugin; private EventChannelPlugin eventChannelPlugin; EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //basicMessageChannelPlugin = BasicMessageChannelPlugin.registerWith(getFlutterEngine().getDartExecutor(), this); setContentView(R.layout.activity_main); editText = findViewById(R.id.editTextTextPersonName); findViewById(R.id.test).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //没有指定路由 传值;只能调到 默认路由(开始界面) // FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); // fragmentTransaction.add(R.id.someContainer, FlutterFragment.createDefault()); // //fragmentTransaction.replace(R.id.someContainer, FlutterFragment.createDefault()); // fragmentTransaction.commit(); // System.out.println("------>"+editText.getText().toString()); //指定路由并且传值 // FlutterFragment flutterFragment = FlutterFragment.withNewEngine() // // .initialRoute("{name:'devio',dataList:['aa','bb','bb']}") // .initialRoute(editText.getText().toString()) // .build(); // getSupportFragmentManager() // .beginTransaction() // .replace(R.id.someContainer, flutterFragment) // .commit(); Intent intent = new Intent(MainActivity.this, FlutterAppActivity.class); intent.putExtra(FlutterAppActivity.INIT_PARAMS, editText.getText().toString()); startActivity(intent); // //第一种 // //緩存的方式 打開FlutterEngine 缺點不能傳參 依赖 MyAppcation // startActivity( // FlutterActivity // .withCachedEngine(MyApplicaiton.CACHED_ENGINE_ID) // .build(MainActivity.this) // ); // // //不不緩存 直接打開;每次都是新的 實例;有點可疑傳參 // startActivity( // FlutterActivity // .withNewEngine() // .initialRoute("{name:'devio',dataList:['aa','bb','bb']}") // .build(MainActivity.this) // ); // // startActivity(FlutterAppActivity.createDefaultIntent(MainActivity.this)); } }); } }
对应的 main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
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(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter 混合开发'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final String initParams = ui.window.defaultRouteName;
late StreamSubscription _streamSubscription;
static const EventChannel _eventChannel = EventChannel("EventChannelPlugin");
static const MethodChannel _methodChannel =
MethodChannel('MethodChannelPlugin');
static const BasicMessageChannel _basicMessageChannel =
BasicMessageChannel<String>('BasicMessageChannelPlugin', StringCodec());
String showMessage = '';
String inputEventChannel = '';
String inputMethodChannel = '';
String inputBasicMessageChannel = '';
@override
void initState() {
// TODO: implement initState
super.initState();
//EventChannel
_streamSubscription = _eventChannel.receiveBroadcastStream('123').listen(
_onEventChannel,
onError: _onErrorEventChannel,
onDone: _onDoneEventChannel);
//使用 BasicMessageChannel 接收来自 native的消息,并向 native回复
_basicMessageChannel.setMessageHandler((message) async {
setState(() {
showMessage = "BasicMessageChannel :" + message;
});
return "收到 Native消息: " + message; //返回给 原生的
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
alignment: Alignment.topCenter,
decoration: BoxDecoration(color: Colors.white),
child: Column(
children: [
Row(
children: [
Expanded(
child: TextField(
onChanged: (str) {
this.inputMethodChannel = str;
},
cursorRadius: Radius.circular(15),
),
),
OutlineButton(
onPressed: () async {
try {
String response = await _methodChannel.invokeMethod(
'send',
inputMethodChannel); //invokeMethod(方法名 , 参数)
setState(() {
showMessage = response;
});
} catch (e) {
print('_methodChannel Error');
showMessage = '_methodChannel Error $e';
}
},
child: Text("methodChannel 主动发送到原生"),
)
],
),
Row(
children: [
Expanded(
child: TextField(
onChanged: (str) {
this.inputBasicMessageChannel = str;
},
cursorRadius: Radius.circular(15),
),
),
OutlineButton(
onPressed: () async {
try {
String response = await _basicMessageChannel
.send(inputBasicMessageChannel);
setState(() {
showMessage = response;
});
} catch (e) {
print('_basicMessageChannel Error');
setState(() {
showMessage = '_basicMessageChannel Error $e';
});
}
},
child: Text("BasicMessage 主动发送到原生"),
)
],
),
Text('初始化参数 :$initParams'),
Row(
children: [
Padding(
padding: EdgeInsets.only(top: 20, right: 20),
child: Text(
'收到原生的数据:',
style: TextStyle(overflow: TextOverflow.visible),
),
),
Flexible(
child: Text(
showMessage,
overflow: TextOverflow.visible,
),
)
],
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _onEventChannel(data) {
setState(() {
showMessage = "EventChannel :" + data;
});
}
void _onErrorEventChannel(error) {}
void _onDoneEventChannel() {}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_streamSubscription.cancel();
//_streamSubscription = null;
}
}
更多推荐


所有评论(0)