当前位置: 首页 > article >正文

Flutter Android Package调用python

操作步骤

一、创建一个Flutter Package

使用以下指令创建一个Flutter Package

flutter create --template=plugin --platforms=android,ios -a java flutter_package_python

二、修改android/build.gradle文件

在buildscript——>dependencies中添加以下内容

//导入Chaquopy插件,使Android可以使用Python
classpath "com.chaquo.python:gradle:15.0.1"

在android上方导入chaquo.python插件

apply plugin: 'com.chaquo.python'

在android——>defaultConfig中添加ndk和python配置

       ndk {
            abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
        }
        python {
            version "3.8"
            pip { 
				//根据python用到的依赖进行下载
                install "scipy"
                install "numpy" 
                install "PyWavelets"
                install "scikit-image"
                install "tflite-runtime"
                install "statsmodels"
            }
        } 

三、编写python文件

在android——>src——>main目录下创建名称为calc的python文件,写一个简单的加法函数:

# calc.py
def add(a, b):
    return a + b

四、创建一个工厂函数,用于初始化Python以及引用Python函数

在android——>src——>main——>com——>expample——>flutter_package_python下创建PythonFactory.java文件,对Python进行初始化,以及调用Python中的加法函数

package com.example.flutter_package_python;

import android.content.Context;
import com.chaquo.python.PyObject;
import com.chaquo.python.Python;
import com.chaquo.python.android.AndroidPlatform;


public class PythonFactory {
    private static PythonFactory instance = null; // 静态实例
    private Python pythonInstance; // Python 环境实例
    private PyObject calcModule; // Python 模块
    private static boolean isInitialized = false;

    // 私有化构造函数,确保外部无法直接实例化
    private PythonFactory(Context context) {
        if (!isInitialized) {
            Python.start(new AndroidPlatform(context)); // 需要传入上下文
            isInitialized = true;
        }
        pythonInstance = Python.getInstance(); // 初始化 Python 环境
        calcModule = pythonInstance.getModule("calc"); // 加载 calc.py 模块
    }

    // 获取单例工厂实例
    public static synchronized PythonFactory getInstance(Context context) {
        if (instance == null) {
            instance = new PythonFactory(context); // 初始化一次
        }
        return instance;
    }

    // 工厂方法:调用 Python 中的加法函数
    public int addTwoNumbers(int a, int b) {
        PyObject result = calcModule.callAttr("add", a, b); // 调用 Python 中的 add 方法
        return result.toInt(); // 将结果返回为整数
    }
}

五、在FlutterPackagePythonPlugin中使用工厂函数

1.定义pythonFactory变量,在onAttachedToEngine中初始化工厂函数并将结果返回给pythonFactory

  private PythonFactory pythonFactory;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
   	// 其他代码
    pythonFactory = PythonFactory.getInstance(flutterPluginBinding.getApplicationContext());
  }

2. 在onMethodCall添加判断,当dart中调用了addTwoNumbers函数则使用Python进行相加计算

if (call.method.equals("addTwoNumbers")) {
      int a = call.argument("a");
      int b = call.argument("b");
      // 使用工厂类调用 Python 的加法函数
      int sum = pythonFactory.addTwoNumbers(a, b);
      result.success(sum); // 将结果返回给 Flutter 端
    }

六、编写dart代码调用安卓中的java

在lib/flutter_packages_audio_analysis_platform_interface.dart中添加一个addTwoNumbers函数

Future<int?> addTwoNumbers(int a, int b) {
    throw UnimplementedError('addTwoNumbers() has not been implemented.');
  }

在lib/flutter_packages_audio_analysis_method_channel.dart中重写addTwoNumbers方法

 @override
  Future<int> addTwoNumbers(int a, int b) async {
    try {
      final result =
          await methodChannel.invokeMethod('addTwoNumbers', {'a': a, 'b': b});
      return result;
    } on PlatformException catch (e) {
      print("调用 Python 失败: '${e.message}'.");
      return -1;
    }
  }

3.在lib/FlutterPackagesAudioAnalysis类中添加addTwoNumbers函数

 Future<int?> addTwoNumbers(int a, int b) {
    return FlutterPackagesAudioAnalysisPlatform.instance.addTwoNumbers(a, b);
  }

七、写测试代码

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

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  final _flutterPackagesAudioAnalysisPlugin = FlutterPackagesAudioAnalysis();

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

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    // We also handle the message potentially returning null.
    try {
      platformVersion =
          await _flutterPackagesAudioAnalysisPlugin.getPlatformVersion() ??
              'Unknown platform version';
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  int addRes = 0;
  add() async {
    int a = 8;
    int b = 9;
    addRes =
        await _flutterPackagesAudioAnalysisPlugin.addTwoNumbers(a, b) ?? 100;
    setState(() {});
  }

  add1() async {
    int a = 8;
    int b = 19;
    addRes =
        await _flutterPackagesAudioAnalysisPlugin.addTwoNumbers(a, b) ?? 100;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text('Running on: $_platformVersion\n'),
              ElevatedButton(onPressed: add, child: Text('Add')),
              Text("相加结果:${addRes}"),
              ElevatedButton(onPressed: add1, child: Text('Add1')),
            ],
          ),
        ),
      ),
    );
  }
}


http://www.kler.cn/news/314627.html

相关文章:

  • 基于深度学习的因果推理与决策
  • 【JVM】运行时数据区
  • Ubuntu 20.04 内核升级后网络丢失问题的解决过程
  • 《DevOps实践指南》笔记-Part 3
  • Swift里的数值变量的最大值和最小值
  • 分布式光伏发电站数据采集设备管理硬件解决方案
  • 机器学习——Stacking
  • C++速通LeetCode中等第21题-排序链表(空间O(1))
  • 828华为云征文 | 华为云X实例的镜像管理详解
  • Unexpected end of file from server 错误
  • 系统架构设计师教程 第5章 5.4 软件测试 笔记
  • 论文阅读笔记:Sapiens: Foundation for Human Vision Models
  • MoCo和SimCLR【CV双雄】
  • mxnet算子调用kernel示例(MINIST)
  • Java面试篇-AOP专题(什么是AOP、AOP的几个核心概念、AOP的常用场景、使用AOP记录操作日志、Spring中的事务是如何实现的)
  • SYN Flood攻击原理,SYN Cookie算法
  • 【数据结构C语言】【入门】【首次万字详细解析】入门阶段数据结构可能用到的C语言知识,一章让你看懂数据结构!!!!!!!
  • 我的AI工具箱Tauri版-FasterWhisper音频转文本
  • 什么是 HTTP/3?下一代 Web 协议
  • 直播音频解决方案
  • PyTorch 实现手写数字识别
  • 2024华为杯数模CDEF成品文章!【配套完整解题代码+数据处理】
  • 一文读懂 JS 中的 Map 结构
  • 图形化编程012(变量-倒计时)
  • 【JVM原理】运行时数据区(内存结构)
  • 前端框架的比较与选择详解
  • 数据库提权【笔记总结】
  • 计算机毕业设计 社区医疗服务系统的设计与实现 Java实战项目 附源码+文档+视频讲解
  • web基础—dvwa靶场(四)​File Inclusion
  • 电脑文件防泄密软件哪个好?这六款软件建议收藏【精选推荐】