Flutter和Native 通信 android端

简介: Flutter和Native 通信 android端

通信用到的类

  1. MethodChannel
  2. EventChannel
  3. BasicMessageChannel
MethodChannel使用方式(flutter 调用原生方法)
1. 原生代码
  1. 定义通信标识
   private val METHOD_CHANNEL = "tip.flutter.io/method"
  1. 创建对象
 MethodChannel((getView() as FlutterView), METHOD_CHANNEL).setMethodCallHandler { call, result ->
           if (call.method == "getBatteryLevel") {
               val ba = getBatteryLevel()
               if (ba != -1) {
                   result.success(ba)
               } else {
                   result.error("UNAVAILABLE", "Battery level not available.", null)
               }
           } else {
               result.notImplemented()
           }
       }
  1. 定义原生方法
  private fun getBatteryLevel(): Int {
        return 123
    }
2. dart代码
  1. 创建对象
  static const platfrom = const MethodChannel("tip.flutter.io/method");
  1. 初始化方法
 Future<Null> _getBatteryLevel() async {
    String batteryLevel;
    try {
      final int result = await platfrom.invokeMethod("getBatteryLevel");
      batteryLevel = 'Battery level at $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }
    setState(() {
      _batteryLevel = batteryLevel;
    });
  }
  1. 调用方法
 @override
  void initState() {
    // TODO: implement initState
    _getBatteryLevel();
    super.initState();
  }
EventChannel使用方式(主要是native向flutter主动推送数据,例如推送电量,网络状态)
BasicMessageChannel使用方式(native->flutter,flutter->native)
完整nativie 代码如下
package com.gctech.nativeandflutter

import android.os.Bundle
import android.os.Handler
import android.view.View
import android.widget.Toast
import io.flutter.facade.FlutterFragment
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.StringCodec
import io.flutter.view.FlutterView
import java.util.*

/**
 *    author: yu.jl
 *    e-mail: bbfx89625@gmail.com
 *    time  : 2019/7/24
 *    desc  :
 */
class FlutterBaseFragment : FlutterFragment() {
    private val METHOD_CHANNEL = "tip.flutter.io/method"
    private val EVENT_CHANNEL = "tip.flutter.io/event"
    private val MESSAGE_CHANNEL = "tip.flutter.io/message"
    private val handler = Handler()
    var mesageChan: BasicMessageChannel<String>? = null

    companion object {
        fun newInstance(router: String) = FlutterBaseFragment().apply {
            arguments = Bundle().apply {
                putString("router", router)
            }

        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        MethodChannel((getView() as FlutterView), METHOD_CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getBatteryLevel") {
                val ba = getBatteryLevel()
                if (ba != -1) {
                    result.success(ba)
                } else {
                    result.error("UNAVAILABLE", "Battery level not available.", null)
                }
            } else {
                result.notImplemented()
            }
        }
        EventChannel((getView() as FlutterView), EVENT_CHANNEL).setStreamHandler(object : EventChannel.StreamHandler {
            override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                Timer().schedule(object : TimerTask() {
                    override fun run() {
                        handler.post {
                            events?.success("当前时间毫秒${System.currentTimeMillis()}")
                        }
                    }
                }, 1000, 1000)
            }

            override fun onCancel(p0: Any?) {
            }

        })
        mesageChan = BasicMessageChannel<String>(
            (getView() as FlutterView),
            MESSAGE_CHANNEL,
            StringCodec.INSTANCE
        )
        mesageChan?.setMessageHandler { a, b ->
            b.reply("aaaa${System.currentTimeMillis()}")
            Toast.makeText(context,a,Toast.LENGTH_LONG).show()
           // Log.e("收到消息", "a=$a=b=${b.reply("aaaa${System.currentTimeMillis()}")}")
        }
    }
    private fun getBatteryLevel(): Int {
        return 123
    }


}
完整dart 代码如下
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      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> {
  int _counter = 0;
  String _batteryLevel = '';
  String _eventStr = '';
  String _mssageStr = '_mssageStr';
  static const platfrom = const MethodChannel("tip.flutter.io/method");
  static const eventChannel = const EventChannel("tip.flutter.io/event");
  static const messageChannel = const BasicMessageChannel<String>(
      "tip.flutter.io/message", StringCodec());
  StreamSubscription _streamSubscripton;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  Future<Null> _getBatteryLevel() async {
    String batteryLevel;
    try {
      final int result = await platfrom.invokeMethod("getBatteryLevel");
      batteryLevel = 'Battery level at $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }
    setState(() {
      _batteryLevel = batteryLevel;
    });
  }

  Future<Null> _msssage() async {
    messageChannel.setMessageHandler((String message) => Future<String>(() {
          print("收到native的消息$message");
          setState(() {
            _mssageStr = message;
          });
          return "收到native的消息$message";
        }));
    String ponse;
    try {
      ponse = await messageChannel.send("我来自flutter");
    } catch (e) {
      print(e);
    }
    setState(() {
      _mssageStr = ponse;
    });
    print(ponse);
  }

  Future<Null> _lisEvent() async {
    String eventStr;
    try {
      _streamSubscripton = eventChannel
          .receiveBroadcastStream()
          .listen(_onToDart, onError: _onToDartError);
    } on PlatformException catch (e) {
      eventStr = "event get data err: '${e.message}'.";
      setState(() {
        _eventStr = eventStr;
      });
    }
  }

  @override
  void dispose() {
    if (_streamSubscripton != null) {
      _streamSubscripton.cancel();
      _streamSubscripton = null;
    }

    // TODO: implement dispose
    super.dispose();
  }

  _onToDart(message) {
    setState(() {
      _eventStr = message;
    });
    print(message);
  }

  _onToDartError(error) {
    print(error);
  }

  @override
  void initState() {
    // TODO: implement initState
    _getBatteryLevel();
    _lisEvent();
    _msssage();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
   
    return Scaffold(
      appBar: AppBar(
        
        title: Text(widget.title),
      ),
      body: Center(
        
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'AAA You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            Text(
              '$_batteryLevel',
            ),
            Text(
              '$_eventStr',
            ),
            Text(
              '$_mssageStr',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

c盘
  1. 修改.gradle 目录
    在Windows的环境变量中新建一个环境变量设置,GRADLE_USER_HOME,值为D:\Users\shaowei.gradle,设置完成之后,点击确定,关闭设置窗口。这个时候可以去AS中看下gradle的用户目录,自动变成了环境变量中的值了
  2. 修改配置文件Pixel_3_XL_API_28.ini
    avd.ini.encoding=UTF-8
    path=D:\avd\Pixel_3_XL_API_28.avd
    path.rel=avd\Pixel_3_XL_API_28.avd
    target=android-28


    相关文章
    |
    2月前
    |
    前端开发 JavaScript Android开发
    Flutter 与 React Native - 详细深入对比分析(2024 年)
    Flutter和React Native是两大跨平台框架,各有优缺点。Flutter性能优越,UI灵活,使用Dart;React Native生态广泛,适合JavaScript开发。
    421 5
    Flutter 与 React Native - 详细深入对比分析(2024 年)
    |
    2月前
    |
    移动开发 Dart 搜索推荐
    打造个性化安卓应用:从零开始的Flutter之旅
    【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
    |
    2月前
    |
    开发框架 移动开发 Android开发
    安卓与iOS开发中的跨平台解决方案:Flutter入门
    【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
    84 7
    |
    3月前
    |
    开发框架 搜索推荐 开发工具
    打造个性化安卓应用:从零开始的Flutter之旅
    【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
    87 15
    |
    3月前
    |
    Dart 开发工具 Android开发
    在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
    在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
    |
    3月前
    |
    开发框架 Dart 前端开发
    Android 跨平台方案对比之Flutter 和 React Native
    本文对比了 Flutter 和 React Native 这两个跨平台移动应用开发框架。Flutter 使用 Dart 语言,提供接近原生的性能和丰富的组件库;React Native 则基于 JavaScript,具备庞大的社区支持和灵活性。两者各有优势,选择时需考虑团队技能和项目需求。
    387 8
    |
    3月前
    |
    Java Android开发 数据安全/隐私保护
    Android中多进程通信有几种方式?需要注意哪些问题?
    本文介绍了Android中的多进程通信(IPC),探讨了IPC的重要性及其实现方式,如Intent、Binder、AIDL等,并通过一个使用Binder机制的示例详细说明了其实现过程。
    347 4
    |
    3月前
    |
    JSON Dart Java
    flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
    flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
    |
    3月前
    |
    安全 Android开发 开发者
    探索安卓开发的未来:Kotlin的崛起与Flutter的挑战
    在移动开发的广阔天地中,安卓平台始终占据着举足轻重的地位。随着技术的不断进步和开发者需求的多样化,Kotlin和Flutter成为了改变游戏规则的新玩家。本文将深入探讨Kotlin如何以其现代化的特性赢得开发者的青睐,以及Flutter凭借跨平台的能力如何挑战传统的安卓开发模式。通过实际案例分析,我们将揭示这两种技术如何塑造未来的安卓应用开发。
    78 6
    |
    4月前
    |
    搜索推荐 IDE 开发工具
    打造个性化安卓应用:从零开始的Flutter之旅
    在数字时代的浪潮中,拥有一款个性化且高效的移动应用已成为许多创业者和企业的梦想。本文将引导你使用Flutter框架,从零基础开始构建一个安卓应用,不仅涉及界面设计、功能实现,还包括性能优化的关键技巧。通过简洁易懂的语言和实用的代码示例,我们将一起探索如何让你的应用在众多竞争者中脱颖而出。 【8月更文挑战第31天】