眾所周知狸膏,python的語法簡潔沟饥,并且擁有豐富強(qiáng)大的開源庫,如果能把python移植到Android系統(tǒng)湾戳,能夠用Android和python混合開發(fā)一款app, 那就太酷了贤旷。
要想移植python,得需要下載源碼并且交叉編譯才行砾脑。這個過程太復(fù)雜幼驶。在這里,介紹一款第三方韧衣,復(fù)雜的過程交給它處理盅藻,我們只需要處理邏輯相關(guān)的python代碼即可购桑。
Chaquopy
0x01 集成
1)打開項(xiàng)目根目錄下的build.gradle文件
buildscript {
repositories {
google()
jcenter()
maven { url "https://chaquo.com/maven" }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "com.chaquo.python:gradle:6.3.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
2)打開module路徑下的build.gradle文件
在頂部添加chaquo插件名稱
apply plugin: 'com.android.application'
apply plugin: 'com.chaquo.python'
android {
compileSdkVersion 28
defaultConfig {
在defaultConfig節(jié)點(diǎn)下添加
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters "armeabi-v7a", "x86"
}
python {
// 指定python路徑
buildPython "D:/python3/python.exe"
// 安裝python庫
pip {
install "numpy"
}
}
其中,pip這個節(jié)點(diǎn)是需要的python庫氏淑,這個根據(jù)自己需要來填寫即可勃蜘,也可以不寫
然后sync一下,到此夸政,集成完畢元旬,可以編寫python代碼了,是不是很方便守问?
3)AndroidStudio安裝python插件匀归,安裝后就可以直接在AS上面寫python代碼(當(dāng)然也可以直接用其他IDE編寫Python腳本)
File --> setting --> Plugins , 搜索Python, 選中Python Community Edition插件, 安裝耗帕,重新啟動AS后穆端,就可以在項(xiàng)目中像創(chuàng)建JAVA類一樣創(chuàng)建python文件了
0x02 編寫代碼
1)編寫python代碼
app --> src --> main下面,創(chuàng)建一個python文件夾
再在文件夾中創(chuàng)建一個python文件py_util.py
開始編寫python代碼
from java import jclass
import numpy as np
def getPerson():
# 此處可以在studio中把log調(diào)成verbose仿便, 過濾填寫stdout
print ("---java 調(diào)用了此方法---")
# 填寫java been的路徑
JavaBean = jclass("com.zgy.python_native.been.Person")
person = JavaBean()
person.setName("神氣小風(fēng)")
person.setAge(25)
return person
def getPerson(parameter):
# 此處可以在studio中把log調(diào)成verbose体啰, 過濾填寫stdout
print ("---java 調(diào)用了此方法---")
# 填寫java been的路徑
JavaBean = jclass("com.zgy.python_native.been.Person")
person = JavaBean()
person.setName("神氣小風(fēng)")
age = parameter + 10
person.setAge(age)
return person
def getNumpyData():
arr = np.array([0.25, 1.33, 1, 100])
list = np.reciprocal(arr)
print (list)
return list
簡單說一下,因?yàn)橐筳ava和python互相調(diào)用嗽仪,所以python要能找到j(luò)ava的類荒勇,能根據(jù)構(gòu)造方法創(chuàng)建對象。所以要引入jclass闻坚,而且在代碼中要寫上java類的路徑沽翔,然后就是數(shù)據(jù)處理,最后把數(shù)據(jù)返回
2)編寫java部分
因?yàn)樯婕暗綄?shí)體類窿凤,所以先創(chuàng)建個been
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
接著仅偎,編寫activity中的代碼,先初始化python
private void init() {
binding.setViewClick(this);
initPython();
}
// 初始化python
private void initPython(){
if (! Python.isStarted()) {
Python.start(new AndroidPlatform(this));
}
}
然后開始調(diào)用python方法,
/**
* 有參數(shù)
*/
private void callPyParametersMethod() {
Python py = Python.getInstance();
PyObject pyObject_person = py.getModule("py_util").callAttr("getPerson", 20);
Person person = pyObject_person.toJava(Person.class);
Log.d(TAG, "[parameters method] person name : " + person.getName() + " age : " + person.getAge());
}
/**
* 無參數(shù)
*/
private void callPySingleMethod() {
Python py = Python.getInstance();
PyObject pyObject_person = py.getModule("py_util").callAttr("getPerson");
Person person = pyObject_person.toJava(Person.class);
Log.d(TAG, "[single method] person name : " + person.getName() + " age : " + person.getAge());
}
/**
* 通過python庫實(shí)現(xiàn)的方法
*/
private void callPyNumpyMethod() {
Python py = Python.getInstance();
PyObject obj3 = py.getModule("py_util").callAttr("getNumpyData");
List<PyObject> pyList = obj3.asList();
Log.d(TAG,"callPyNumpyMethod = " + pyList.toString());
}
Python.getInstance() : 得到python的對象
py.getModule("py_util") : 是調(diào)用哪個.py文件
callAttr("getPerson", 20) : 第一個參數(shù)表示調(diào)用的python中的方法名雳殊,后面是方法的參數(shù)橘沥。
好了,到此已經(jīng)全部完成了夯秃,跑起來座咆,運(yùn)行,發(fā)現(xiàn)仓洼,java中能夠獲取到python中的數(shù)據(jù)了箫措。