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月前
    |
    开发框架 前端开发 Android开发
    Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
    本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
    264 4
    |
    4天前
    |
    Dart 前端开发 Android开发
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    |
    2月前
    |
    前端开发 数据处理 Android开发
    Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
    本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
    69 8
    |
    3月前
    |
    前端开发 JavaScript Android开发
    Flutter 与 React Native - 详细深入对比分析(2024 年)
    Flutter和React Native是两大跨平台框架,各有优缺点。Flutter性能优越,UI灵活,使用Dart;React Native生态广泛,适合JavaScript开发。
    1140 5
    Flutter 与 React Native - 详细深入对比分析(2024 年)
    |
    3月前
    |
    移动开发 Dart 搜索推荐
    打造个性化安卓应用:从零开始的Flutter之旅
    【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
    |
    2月前
    |
    开发框架 Dart Android开发
    安卓与iOS的跨平台开发:Flutter框架深度解析
    在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
    |
    3月前
    |
    开发框架 移动开发 Android开发
    安卓与iOS开发中的跨平台解决方案:Flutter入门
    【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
    120 7
    |
    4月前
    |
    Dart 开发工具 Android开发
    在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
    在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
    |
    开发工具 Android开发
    Flutter Unable to locate Android SDK.
    Flutter Unable to locate Android SDK.
    444 0
    Flutter Unable to locate Android SDK.
    |
    1月前
    |
    搜索推荐 前端开发 API
    探索安卓开发中的自定义视图:打造个性化用户界面
    在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
    65 19