Flutter Android Package调用python

发布于:2024-09-19 ⋅ 阅读:(12) ⋅ 点赞:(0)

操作步骤

一、创建一个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')),
            ],
          ),
        ),
      ),
    );
  }
}


网站公告

今日签到

点亮在社区的每一天
去签到