Flutter Android Package调用python

news/2024/9/18 20:36:30 标签: flutter, android, 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.niftyadmin.cn/n/5664484.html

相关文章

【2024】前端学习笔记7-颜色-位置-字体设置

学习笔记 1.定义&#xff1a;css2.颜色&#xff1a;color3.字体相关属性&#xff1a;font3.1.字体大小&#xff1a;font-size3.2.字体风格&#xff1a;font - style3.3.字体粗细&#xff1a;font - weight3.4.字体族&#xff1a;font - family 4.位置&#xff1a;text-align 1.…

如何看待IBM中国研发部裁员?

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; IBM中国研发部裁员及撤出背景分析 IBM&#xff08;International Business Machines&#xff09;作为全球科技巨头之一&#xff0c;其在中国市场的发展曾是中国信息技术产业的重要组成部分。近年来&#x…

图片转PDF技巧揭秘:四款高效工具推荐!

在数字化办公和学习的今天&#xff0c;将图片或其他文件格式转换为PDF已成为一种常见需求。以下是几款推荐的转换工具&#xff0c;它们各自具有独特的功能和使用体验&#xff0c;可帮助大家轻松实现图片转PDF及其他PDF相关操作。 福昕PDF转换大师&#xff08;365客户端&#x…

Yestar成都艺星引领行业星纪元:十大数字星品·高阶星技术震撼发布

近日&#xff0c;中国成都太古里Yestar十大数字星品高阶星技术AI科技3D Mapping全球发布会&#xff0c;震撼发布了十大数字星品高阶星技术升级&#xff0c;引领医美产业发展翻开崭新的一页。作为品牌成立19周年的庆典&#xff0c;这场科技与美学交融的盛会&#xff0c;标志着医…

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—你的透明背景图片生成工具

大家好&#xff0c;我是灵魂画师向阳 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可…

战神诸神黄昏9月19日登录PC端! 手机怎么玩战神诸神黄昏

9月19日&#xff0c;《战神&#xff1a;诸神黄昏》正式登录PC端&#xff0c;这是一部动作冒险游戏。要是你想随时随地在手机或平板上也能玩《战神&#xff1a;诸神黄昏》&#xff0c;可以使用网易GameViewer远程帮你实现。 网易GameViewer远程作为一款专为游戏玩家打造的远程软…

Java 读取特定目录下子文件夹的 json格式文件并解析

一、需求   有一个目录结构&#xff0c;包含多个子文件夹&#xff0c;每个子文件夹中都有一个名为goods.txt的文件&#xff0c;文件内容以 JSON 格式存储。现在需要将所有的goods.txt文件内容读取出来&#xff0c;放在一个List集合中&#xff0c;以便进行后续的处理。 二、使…

数字化转型全攻略:构建未来企业的数字化业务知识体系,助力企业腾飞

数字化转型如何为企业带来新机遇 在当今竞争激烈的市场中&#xff0c;数字化转型已经成为每个企业的生存之道。企业通过大数据、人工智能、物联网等技术&#xff0c;不仅提升了运营效率&#xff0c;还彻底改变了客户体验。然而&#xff0c;数字化转型并非只是简单的技术实施&a…