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"
}
如图所示:
图中install后的库为我的项目使用到的第三方库,请按照各自代码需要修改成对应的库名,大部分第三方库都已经支持,详情请看chaquopy的官方链接:https://chaquo.com/pypi-7.0/
修改完成后,需要Sync项目来进行安装这些第三方库,成功之后,继续在之前新建的python文件中进行代码编写。
在编写代码的过程中可能会提示没有Python解释器或者import第三方库是显示红色下划线,如图所示:
这种情况不用在意,只要你前文配置过程没有出错,这里就不用在意,因为之后程序是可以正常运行的。另外提醒,在这里编写代码,没有代码补全功能,所以需要注意代码细节。
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中的数据进行打印输出。