Flutter跟Native交互

先看一眼官方提供的demo:
Native端:

public class MainActivity extends FlutterActivity {

  private String sharedText;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_SEND.equals(action) && type != null) {
      if ("text/plain".equals(type)) {
        handleSendText(intent); // Handle text being sent
      }
    }

    new MethodChannel(getFlutterView(), "app.channel.shared.data").setMethodCallHandler(
      new MethodCallHandler() {
        @Override
        public void onMethodCall(MethodCall call, MethodChannel.Result result) {
          if (call.method.contentEquals("getSharedText")) {
            result.success(sharedText);
            sharedText = null;
          }
        }
      });
  }

  void handleSendText(Intent intent) {
    sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
  }
}

flutter端:

void main() {
  runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample Shared App Handler',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  static const platform = const MethodChannel('app.channel.shared.data');
  String dataShared = "No data";

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(body: Center(child: Text(dataShared)));
  }

  getSharedText() async {
    var sharedData = await platform.invokeMethod("getSharedText");
    if (sharedData != null) {
      setState(() {
        dataShared = sharedData;
      });
    }
  }
}

注意:app.channel.shared.data两端保持一致。

一、 交互方式

* BasicMessageChannel:用于传递字符串和半结构化的信息,这个用的比较少

* MethodChannel:用于传递方法调用(method invocation)通常用来调用native中某个方法

* EventChannel: 用于数据流(event streams)的通信。有监听功能,比如电量变化之后直接推送数据给flutter端。

二、 channel通信的数据类型
在这里插入图片描述
在这里你不能传递一个bean文件过去。
三、使用方法

  1. MethodChannel可以直接看官方给的代码就好,其中Native中onMethodCall的Result对象是回调数据给flutter中使用的,有三个方法:
result.success(data);     成功的时候,返回数据调用
result.error()            失败的情况下,调用
result.notImplemented();  这个是代表Native中的方法没有实现的话,可以告诉flutter方法没有实现

1.1 双向通讯
举个例子,我们想从Native端请求Flutter端的一个getFlutterName方法获取一个字符串。在Flutter端你需要给MethodChannel设置一个MethodCallHandler:

platform.setMethodCallHandler(platformCallHandler);

Future<dynamic> platformCallHandler(MethodCall call) async {
    switch (call.method) {
            case "getFlutterName":
            return "Flutter name flutter";
            break;
    }
}

在Native端,只需要让对应的的channel调用invokeMethod就行了:

channel.invokeMethod("getFlutterName", null, new MethodChannel.Result() {
      @Override
      public void success(Object o) {
        // 这里就会输出 "Flutter name flutter"
        Log.i("debug", o.toString());
      }
      @Override
      public void error(String s, String s1, Object o) {
      }
      @Override
      public void notImplemented() {
      }
    });
  1. EventChannel的使用
    官方给了一个获取电池电量的demo
    Native端:
public class FlutterEventChannel implements EventChannel.StreamHandler {

    private static final String TAG = "FlutterEventChannel";
    private static final String EVENT_CHANNEL_NAME = "com.meetyou.flutter/event";

    private FlutterEventChannel(FlutterView flutterView) {
        EventChannel eventChannel = new EventChannel(flutterView, EVENT_CHANNEL_NAME);
        eventChannel.setStreamHandler(this);
    }

    public static FlutterEventChannel create(FlutterView flutterView) {
        return new FlutterEventChannel(flutterView);
    }

    private EventChannel.EventSink eventSink;

    /**
     * 暴露出去供界面传数据到Flutter
     */
    public void sendEvent(Object data) {
        if (eventSink != null) {
            eventSink.success(data);
        } else {
            LogUtils.e(TAG, "===== FlutterEventChannel.eventSink 为空 需要检查一下 =====");
        }
    }

    @Override
    public void onListen(Object o, EventChannel.EventSink eventSink) {
        this.eventSink = eventSink;
    }

    @Override
    public void onCancel(Object o) {
        eventSink = null;
    }
}

后续数据传输

private BroadcastReceiver createChargingStateChangeReceiver(final EventSink events) {
    return new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);

        if (status == BatteryManager.BATTERY_STATUS_UNKNOWN) {
          events.error("UNAVAILABLE", "Charging status unavailable", null);
        } else {
          boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                               status == BatteryManager.BATTERY_STATUS_FULL;
          // 把电池状态发给Flutter
          events.success(isCharging ? "charging" : "discharging");
        }
      }
    };
  }

flutter端:

static const EventChannel eventChannel =
      const EventChannel('com.meetyou.flutter/event');
      
@override
  void initState() {
    super.initState();
    eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
  }

在收到event以后的处理是在_onEvent函数里:

void _onEvent(Object event) {
    setState(() {
      _chargingStatus =
          "Battery status: ${event == 'charging' ? '' : 'dis'}charging.";
    });
  }

  void _onError(Object error) {
    setState(() {
      _chargingStatus = 'Battery status: unknown.';
    });
  }

从Native端传过来的"charging"/"discharging"字符串直接就是入参event.

有关可以参考的文章还有:
Flutter 实例 - 从本地到Flutter通信 - Event Channels
flutter通讯
深入理解Flutter Platform Channel

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值