Flutter与Android原生交互

记录一下小白的学习之路,图片都是走过的坑
文末附demo地址

创建project

首先创建Flutter Project,Android Studio集成flutter开发环境自行百度,语言我选择了Kotlin,不熟悉的可以选择Java,不要忘记勾选 Create project offline,否则会让你等到地老天荒
创建Flutter Project
创建一个离线工程
创建成功后的界面是这个样子
Flutter工程目录
Flutter 定义了三种不同的 Channel

MethodChanel:用于传递方法调用(method invocation)
EventChannel:用于事件流的发送(event streams)
MessageChannel:用于传递字符串和半结构化的消息

*这里是抄的,嘿嘿嘿*

此间只说下MethodChanel

Android端(native)

为了方便开发,我们用Android Studio打开android目录
用Android Studio打开android目录
打开后的目录如下,其中flutterplugin、OneActivity、SeconActivity是我后添加的,其他是自动生成在这里插入图片描述
首先,创建MethodChannel,在FlutterPlugin定义final类型的CHANNEL,通常为“包名/标识”,这里一定要和跟flutter中使用相同的注册字符串,否则无法完成互调。registerWith方法用于注册渠道。然后,设置MethodCallHander,methodCall中传递来自flutter的参数,通过result返回给flutter结果。本案例做了4个操作,详见注释


public class FlutterPlugin implements MethodChannel.MethodCallHandler {

    public static final String CHANNEL = "com.example.flutter_demo2/jump_plugin";
    static MethodChannel channel;

    private Activity activity;
    private FlutterPlugin(Activity activity) {
        this.activity = activity;
    }

    public static void registerWith(FlutterEngine flutterEngine, FlutterActivity activity) {
        channel = new MethodChannel(flutterEngine.getDartExecutor(), CHANNEL);
        FlutterPlugin instance = new FlutterPlugin(activity);
        //setMethodCallHandler在此通道上接收方法调用的回调
        channel.setMethodCallHandler(instance);
    }

    @Override
    public void onMethodCall(MethodCall call, MethodChannel.Result result) {
        //通过MethodCall可以获取参数和方法名,然后再寻找对应的平台业务
        //接收来自flutter的指令,trun2Second跳转到原生的第二个页面
        if (call.method.equals("trun2Second")) {
            //跳转到指定Activity
            Intent intent = new Intent(activity, SecondActivity.class);
            activity.startActivity(intent);

            //返回给flutter的参数
            result.success("success");
        }
        //接收来自flutter的指令,获取flutter传递过来的参数
        else if (call.method.equals("mapData")) {
            //解析参数
            String value = call.argument("flutter");

            Log.v("debug", value);

            Toast.makeText(activity, value, Toast.LENGTH_SHORT).show();
            //返回给flutter的参数
            result.success("success");
        }
        //接收来自flutter的指令,flutter调用原生方法传多个参数并取得返回值
        else if (call.method.equals("getNativeResult")) {
            //解析参数
            String value1 = call.argument("key1");
            String value2 = call.argument("key2");
            Log.v("debug", value1 + value2);

            //返回给flutter的参数
            result.success("success");
        }else if(call.method.equals("goBack")){
        	//flutter返回到上一页原生界面
            activity.finish();
        }
        else {
            result.notImplemented();
        }
    }

再来看MainActivity,继承FlutterActivity
覆写configureFlutterEngine方法,给此类注册组件

class MainActivity: FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        //给当前页面注册组件
        FlutterPlugin.registerWith(flutterEngine, this)
    }
}

注意:
application需要增加主题,否则报错
Android的启动页换成OneActivity,否则启动会直接跳转到flutter页
从OneActivity 跳转到flutter页:

class OneActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_one)
    }

	//点击按钮跳转
    fun turn2flutter(view: android.view.View) {
        val intent = Intent()
        intent.setClass(this,MainActivity::class.java)
        startActivity(intent)
    }
}

Flutter端

创建MethodChannel,并注册channel名,这里再提醒一下,要与native里“包名/标识”的一致
通过invokeMethod发起异步调用,invokeMethod接受两个参数:
method:调用的native方法名
arguments:nativie方法参数,有多个参数时需要以map形式指定

import 'dart:async';

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(
        primarySwatch: Colors.blue,
        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> {

  //获取插件与原生Native的交互通道
  static const platForm = const MethodChannel('com.example.flutter_demo2/jump_plugin');
  //具体要做的功能
  void _goToNativeActivity() async {
    String result = await platForm.invokeMethod('trun2Second');
    print(result);
  }

  // 具体要做的功能
  void _sendDataToNative() async {
    Map<String, String> map = {"flutter": "我是flutter 传递过来的"};
    String result = await platForm.invokeMethod('mapData', map);
    print(result);
  }

  String nativeBackString = 'Not return';

  void _invokeNativeGetResult() async {
    String backString;
    try {
      // 调用原生方法并传参,以及等待原生返回结果数据
      var result = await platForm.invokeMethod('getNativeResult', {'key1':'flutter参数1','key2':'flutter参数2'});
      backString = 'Native return $result';
    } on PlatformException catch (e) {
      backString = "Failed to get native return: '${e.message}'.";
    }
    setState(() {
      nativeBackString = backString;
    });
  }

  void _goBackToNative(){
    if (Navigator.canPop(context)) {  // 返回上一页
      Navigator.of(context).pop();
    } else {
      platForm.invokeMethod('goBack');
    }
  }

  @override
  void initState() {
    super.initState();
    }


  @override
  Widget build(BuildContext context) {
    // flutter 注册原生监听方法
    return new Scaffold(
      appBar: AppBar(
        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(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[

            RaisedButton(
              child: Text('跳转到第二个原生页面'),
              onPressed: () {
                _goToNativeActivity();
              },
            ),
            RaisedButton(
              child: Text('flutter向原生传递数据'),
              onPressed: () {
                _sendDataToNative();
              },
            ),
            RaisedButton(
              child: Text('调用原生方法并传参'+'\n原生传递过来的值 $nativeBackString'),
              onPressed: () {
                _invokeNativeGetResult();
              },
            ),

            RaisedButton(
              child: Text('返回第一个原生界面'),
              onPressed: () {
                _goBackToNative();
              },
            ),
          ],
        ),
      ),
    );
  }

}

Android调用flutter

Android调用flutter类似,注意调用要在UI线程进行


            //android调用flutter方法 并获取结果
            channel.invokeMethod("flutterMedia", "from android", new MethodChannel.Result() {
                @Override
                public void success(Object o) {
                    // 这里就会输出"Hello from Flutter"
                    Log.i(">>>>>>>>>>debug", o.toString());
                }
                @Override
                public void error(String s, String s1, Object o) {
                }

                @Override
                public void notImplemented() {

                }
            });

flutter里实现MethodCallHandler的注册:

Future<dynamic> _platformCallHandler(MethodCall call) async {
    switch (call.method) {
      case 'flutterMedia':
        print('call flutterMedia: arguments = ${call.arguments}');
        return Future.value('Hello from Flutter!');
        //return Future.error('error message!!');
      default:
        print('Unknowm method ${call.method}');
        throw MissingPluginException();
        break;
    }
  }
 
  @override
  initState() {
    super.initState();
 
    // Platforms -> Dart
    _channel.setMethodCallHandler(_platformCallHandler);
  }

demo下载:https://github.com/gaoscxy/flutter_demo

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值