????????在《flutter-boost的集成与基本使用(android与flutter的混合开发)》中提到了在大部分情况下,我们不满足于简单的跳转,想要android原生和flutter进一步的融合,需要借助MethodChannel,利用它我们可以更好的完成原生与flutter页面的数据交互。
? ? ? ? 一、MethodChannel的实现:
? ? ? ? ? ? ? ? (1)在android中,可以定义一个flutterPlugin,进行集中管理,代码如下:
package com.innovation.projector.plugin
import android.widget.Toast
import com.innovation.projector.MyApplication
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry
class FlutterNativePlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
//name必须和dart端的保持一致
val channel = MethodChannel(binding.flutterEngine.dartExecutor, "com.innovation/name")
channel.setMethodCallHandler(FlutterNativePlugin())
}
companion object {
fun registerWith(registrar: PluginRegistry.Registrar) {
val channel = MethodChannel(registrar.messenger(), "com.innovation/name")
channel.setMethodCallHandler(FlutterNativePlugin())
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
}
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"androidMethodTest" -> result.success("android原生执行::" + call.arguments.toString() + call.method)
"androidMethodToast" -> {
Toast.makeText(
MyApplication.getGlobalContext(),
call.arguments.toString(),
Toast.LENGTH_LONG
).show()
//result.success可以将接口返回的数据回传给flutter
result.success("python")
}
else -> result.notImplemented()
}
}
}
? ? ? ? ? ? ? ? (2)在需要调用的activity中重写以下方法:
@Override
public void configureFlutterEngine(@NonNull @NotNull FlutterEngine flutterEngine) {
flutterEngine.getPlugins().add(new FlutterNativePlugin());
}
? ? ? ? ? ? ? ? (3)上面两步完成后,android端也就实现完毕,接下来dart端:
class AddDevicesPage extends StatefulWidget {
final String title;
AddDevicesPage({Key key, this.title}) : super(key: key);
@override
_AddDevicesPageState createState() => _AddDevicesPageState(title);
}
class _AddDevicesPageState extends State<AddDevicesPage>
with PageVisibilityObserver {
String title;
String result='保存';
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.white,
),
home: Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
CommonTitleView(title, 1, null),
Container(
color: Colors.blue,
//在这里体现
child: GestureDetector(
onTap: () async {
await androidMethodTest();
},
child: Text(
result,
style: TextStyle(fontSize: 12, color: Colors.white),
),
),
),
],
),
),
);
}
_AddDevicesPageState(this.title);
Future<String> androidMethodTest() async {
const platform = const MethodChannel('com.innovation/name');
String result = "";
try {
result = await platform.invokeMethod('androidMethodToast', "test");
//接受回调返回的参数,这里进行界面刷新提供更直观的效果
setState(() {
this.result = result;
});
} on Exception catch (e) {
print(e.toString());
}
return result;
}
}
? ? ? ? 二、糅合flutter-boost与MethodChannel的关键:
? ? ? ? ? ? ? ? 闲鱼技术团队提供的flutter-boost在跳转时会使用一个flutterboostactivity作为容器,在上一篇文章中的androidmanifest中提到,如果仅需要我们实现简单带参跳转,我们无需写出实例的activity,如果想两者一并使用,只需下面几步:
? ? ? ? ? ? ? ? (1)在androidmanifest中申明一个新activity,以ToFlutterActivity为例:
<!-- 这里的activity是给flutter跳转native留的 -->
<activity android:name=".ToAndroidActivity" />
<!-- 这里的activity是给直接使用flutterboost进行跳转flutter页面留的原生activity容器 -->
<activity
android:name="com.idlefish.flutterboost.containers.FlutterBoostActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:theme="@style/Theme.FlutterTheme"
android:windowSoftInputMode="adjustResize">
<!--低端机上flutter-boost仍会出现跳转黑屏现象,这种方法可以解决,原理就是类似于原生闪屏页-->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- 这里的activity是给使用flutterboost进行跳转并且想调用原生方法的flutter页面留的原生activity容器 -->
<activity
android:name=".ToFlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:theme="@style/Theme.FlutterTheme"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
</activity>
<activity android:name="io.flutter.embedding.android.FlutterActivity" />
? ? ? ? ????????(2)在自己的application中完成flutter-boost跳转的配置:
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
//alibaba flutter_booster android端配置集成
FlutterBoost.instance().setup(this, new FlutterBoostDelegate() {
@Override
public void pushNativeRoute(FlutterBoostRouteOptions options) {
//这里的ToAndroidActivity是自己定义的,作为flutter跳原生的页面
Intent intent = new Intent(FlutterBoost.instance().currentActivity(), ToAndroidActivity.class);
FlutterBoost.instance().currentActivity().startActivityForResult(intent, options.requestCode());
}
@Override
public void pushFlutterRoute(FlutterBoostRouteOptions options) {
//这里的ToFlutterActivity是自己定义的,作为原生跳flutter页面的容器
Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(ToFlutterActivity.class)
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.destroyEngineWithActivity(false)
.uniqueId(options.uniqueId())
.url(options.pageName())
.urlParams(options.arguments())
.build(FlutterBoost.instance().currentActivity());
FlutterBoost.instance().currentActivity().startActivity(intent);
}
}, engine -> {
});
????????????????(3)将ToFlutterActivity继承FlutterBoostActivity,重写onCreate()方法:
public class ToFlutterActivity extends FlutterBoostActivity {
final private String TAG = "ToFlutterActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
@Override
public void configureFlutterEngine(@NonNull @NotNull FlutterEngine flutterEngine) {
flutterEngine.getPlugins().add(new FlutterNativePlugin());
}
}
·? ? ? ? 以上就是糅合flutter-boost与MethodChannel的使用方法,如有不足,还望讨论。
|