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.java
package 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.java
package 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.java
package 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.java
package 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;
}
}
|