Android studio中编写Python代码-2

Chaquopy 教程

Chaquopy

官方链接:https://chaquo.com/chaquopy/

Chaquopy的作用:使用Chaquopy在Android Studio添加Python环境,java和Python互调

目前调试后APP可以正常运行(2020年7月28日)

上一篇文章已经介绍了在Android studio配置chaquopy的步骤,接下来介绍如何在Android studio中运行Python代码。


安装第三方库

在配置步骤完成后,右击前文提及的src/main目录下名为“python”的文件夹,在“new”中选择“Python File”新建Python文件,取名后,就可以开始在Android studio中编写Python代码。和在其他Python IDE中一样,如果不安装第三方库,那么只能使用一些内置库,但是一般大多时候我们需要使用到第三方库,一般的方法是使用“pip”命令进行安装,而Android studio中实现的方法有一些不一样。

在在app/build.gradle文件的如下位置处编写代码:

pip{
        install "opencv-python"
        install "numpy"
        install "wave"
        install "scipy"
        install "matplotlib"
    }

如图所示:

pythonpip

图中install后的库为我的项目使用到的第三方库,请按照各自代码需要修改成对应的库名,大部分第三方库都已经支持,详情请看chaquopy的官方链接:https://chaquo.com/pypi-7.0/
修改完成后,需要Sync项目来进行安装这些第三方库,成功之后,继续在之前新建的python文件中进行代码编写。
在编写代码的过程中可能会提示没有Python解释器或者import第三方库是显示红色下划线,如图所示:
pythoninterface

这种情况不用在意,只要你前文配置过程没有出错,这里就不用在意,因为之后程序是可以正常运行的。另外提醒,在这里编写代码,没有代码补全功能,所以需要注意代码细节。

Java中调用Python代码

编写完Python代码后,接下来介绍如何在其他Java函数中调用Python代码。
首先需要导入chaquopy的相关类:

import com.chaquo.python.Kwarg; 
import com.chaquo.python.PyObject;
import com.chaquo.python.android.AndroidPlatform;
import com.chaquo.python.Python;

Kwarg与函数传参有关的类;PyObject与变量有关的类;AndroidPlatform初始化Python环境需要的类Python调用Python代码必须要的接口类。
调用Python前首先需要初始化Python的环境:

// 初始化Python环境
    void initPython(){
        if (! Python.isStarted()) {
            Python.start(new AndroidPlatform(this));
        }
    }

初始化完成后,创建一个连接Python的接口:

Python py = Python.getInstance();

再调用Python代码:

PyObject obj1 = py.getModule("workFlow").callAttr("wav2picture",new Kwarg("wav_path", path),new Kwarg("pic_path", pic_path));

其中"workFlow"为需要调用的Python文件名,"wav2picture"为需要调用的函数名,"new Kwarg("wav_path", path),new Kwarg("pic_path", pic_path)" 表示函数的形参“wavp_path”传入path的值,形参“pic_path”传入pic_path的值,obj1表示调用函数之后的返回值,因为Python中的数据类型和Java中有些不一样,所以一般不能直接使用,需要进行转换,比如:

1.如果Python函数return(以上述obj1为例)为int类型,需要使用一下语句进行转换:  
Integer result = obj1.toJava(Integer.class);  

2.如果Python函数return为一维int的list类型,使用以下语句进行转换:  
int[] result = obj1.toJava(int[].class);

3.如果Python函数return为二维int的list类型,使用以下语句进行转换:  
int[][] result = obj1.toJava(int[][].class);

以上的int可以按照实际情况替换成float,double等数据类型,转换语句的主要结构是:

Java数据类型 Java数据变量名 = obj1.toJava(Java数据类型.class)

这样就转换后的Java数据变量就是调用Python代码后的返回结果。


这样就完成了在Android studio中调用Python代码。

补充内容:Python中调用Java类

其实在Python代码也可以反向的调用Java类,但是这部分实际作用并不大,因为整体流程是在Python中先调用Java类,再使用Java调用Python进行后续操作,所以过程比较繁琐,只当做补充内容即可。
假设现在有一个名为"Javatest"的Java类,代码如下:

package com.xzh.test.python;
    import android.util.Log;
    import java.util.ArrayList;
    import java.util.List;

    public class Javatest {
        private String name;
        private List<String> data;
    
        public Javatest(String n){
            this.name = n;
            data = new ArrayList<String>();
        }
    
        public void setData(String el){
            this.data.add(el);
        }
    
        public void print(){
            for (String it: data) {
                Log.d("Javatest - "+this.name,it);
            }
        }
    }

主要包含构造函数,setdata函数用来给list添加数据,print函数用来将list数据打印输出。
在名为"test.py"的文件中编写一段调用Java类的Python代码,如下:

from java import jclass
    # python调用Java类
    def get_java_test():
        Javatest = jclass("com.xzh.test.python.Javatest")#用自己的包名
        jb = Javatest("python")
        jb.setData("json")
        jb.setData("xml")
        jb.setData("xhtml")
        return jb

以上操作分别是指定包名、创建类、list添加三个数据、返回这个类。
在Java中调用这段Python代码的语句如下:

// Python中调用Java类
    PyObject obj2 = py.getModule("test").callAttr("get_java_test");
    Javatest data = obj2.toJava(Javatest.class);
    data.print();

这样程序最终的效果会输出"json"、"xml"和"xhtml"。程序首先会调用Python代码,Python代码依次完成创建类和list添加数据的操作,返回给obj2,obj2再经过类型转换,变成Java类,Java类再正常的调用对应类的输出函数,将list中的数据进行打印输出。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。