一,通过CLE 实现
CLE官网
http://www.srplab.com/cn/files/products.html
下载
1,打开官网下载Android平台对应的download和android.python.x.x.x版本,这两个都要下载;
2,download下的文件提供了不同API平台使用的.so库(例如:armeabi下的libstar_java.so,libstar_python.so,libstarcore.so,libstarpy.so,也就是出libpython3.9.so库之外的都有此提供)及starcore_android_r3.78.jar包等;而libpython3.9.so在android.python.3.9.0下;
3,而android.python.x.x.x提供的主要是使用python语言所使用的到各种python库,比如使用python解压缩使用的zip库对应的CLE中是zlib.cpython-39.so;此文件主要是放在Android项目结构中的assets目录下的,要想使用这些文件必须先复制到app私有目录下比如:data/data/包名/files/;
具体使用
使用的是python3.9.0
1,将下载好的download(例如:starcore_for_android.3.7.8.zip)解压,把libstar_java.so,libstar_python.so,libstarcore.so,libstarpy.so复制到项目的libs/armeabi/下,将starcore_android_r3.78.jar放到Android项目的lib/下;此步骤如果没有上面说的目录需要手动创建;
别忘了在module下的build.gradle配置,因为.so默认目录是src/main/jniLibs下
// jni配置
sourceSets {
main {
jniLibs.srcDirs = ['libs']
jni {
srcDirs 'src\\main\\jni'
}
}
}
和
ndk{
abiFilters "armeabi"
}
2,解压上面下载好的android.python.x.x.x(x.x.x是版本好,根据自己需要下载对应的版本号即可),把libpython3.9.so复制到Android项目的lib/armeabi/下;python3.9.zip和自己要使用的python库例如:zlib.cpython-39.so,binascii.cpython-39.so,_struct.cpython-39.so复制到Android项目的assets目录下;并创建Java调用的python文件名字:MathTest.py和python中调用Java代码的python文件名字:test_calljava.py;
MathiTest.py
def add(a,b):
return a+b
test_calljava.py
import imp #test load path
import json
print(JavaClass)
val = JavaClass("from python")
val.callback(1234.4564)
val.callback("sdfsdfsdfsdf")
val.SetPythonObject(json);
print("===========end=========")
3,Android项目的创建一个Activity在此页面重点用python总的代码;实现加法的逻辑具体如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.Host = this;
}
public StarSrvGroupClass srvGroup;
public static MainActivity Host;
public void click(View view) {
File destDir = new File("/data/data/" + getPackageName() + "/files");
if (!destDir.exists())
destDir.mkdirs();
java.io.File python2_7_libFile = new java.io.File("/data/data/" + getPackageName() + "/files/python3.9.zip");
if (!python2_7_libFile.exists()) {
try {
copyFile(this, "python3.9.zip", null);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
copyFile(this, "_struct.cpython-39.so", null);
copyFile(this, "binascii.cpython-39.so", null);
copyFile(this, "zlib.cpython-39.so", null);
copyFile(this, "test_calljava.py", null);
} catch (Exception e) {
System.out.println(e);
}
String pystring = null;
try {
AssetManager assetManager = getAssets();
InputStream dataSource = assetManager.open("MathTest.py");
int size = dataSource.available();
byte[] buffer = new byte[size];
dataSource.read(buffer);
dataSource.close();
pystring = new String(buffer);
} catch (IOException e) {
System.out.println(e);
}
try {
//--load python34 core library first;
System.load(this.getApplicationInfo().nativeLibraryDir + "/libpython3.9.so");
} catch (UnsatisfiedLinkError ex) {
System.out.println(ex.toString());
}
/*----init starcore----*/
StarCoreFactoryPath.StarCoreCoreLibraryPath = this.getApplicationInfo().nativeLibraryDir;
StarCoreFactoryPath.StarCoreShareLibraryPath = this.getApplicationInfo().nativeLibraryDir;
StarCoreFactoryPath.StarCoreOperationPath = "/data/data/" + getPackageName() + "/files";
StarCoreFactory starcore = StarCoreFactory.GetFactory();
Integer s = new Random().nextInt(100);
StarServiceClass service = starcore._InitSimple("MathTest" + s, "123", 0, 0);
srvGroup = (StarSrvGroupClass) service._Get("_ServiceGroup");
service._CheckPassword(false);
/*----run python code----*/
srvGroup._InitRaw("python39", service);
StarObjectClass python = service._ImportRawContext("python", "", false, "");
python._Call("import", "sys");
StarObjectClass pythonSys = python._GetObject("sys");
StarObjectClass pythonPath = (StarObjectClass) pythonSys._Get("path");
pythonPath._Call("insert", 0, "/data/data/" + getPackageName() + "/files/python3.9.zip");
pythonPath._Call("insert", 0, this.getApplicationInfo().nativeLibraryDir);
pythonPath._Call("insert", 0, "/data/data/" + getPackageName() + "/files");
python._Call("execute", pystring);
Object object = python._Call("add", 11, 22);
Toast.makeText(this,object.toString(),Toast.LENGTH_LONG).show();
String CorePath = "/data/data/" + getPackageName() + "/files";
python._Set("JavaClass", CallBackClass.class);
service._DoFile("python", CorePath + "/test_calljava.py", "");
}
private void copyFile(Activity c, String Name, String desPath) throws IOException {
File outfile = null;
if (desPath != null)
outfile = new File("/data/data/" + getPackageName() + "/files/" + desPath + Name);
else
outfile = new File("/data/data/" + getPackageName() + "/files/" + Name);
outfile.createNewFile();
FileOutputStream out = new FileOutputStream(outfile);
byte[] buffer = new byte[1024];
InputStream in;
int readLen = 0;
if (desPath != null)
in = c.getAssets().open(desPath + Name);
else
in = c.getAssets().open(Name);
while ((readLen = in.read(buffer)) != -1) {
out.write(buffer, 0, readLen);
}
out.flush();
in.close();
out.close();
}
}
总结:以上使用python3.9版本,网上很多都是复制CLE官网的demo ,也有很多bug,很多也没说清楚两个下载文件的用处,导致学习成本很高,所以才总结有了此文章,走过路过别忘了一键三连哦;
想要整个项目的点这里:https://github.com/lz-ang/AndroidMutualPython/tree/master
二,通过sl4a实现
https://github.com/damonkohler/sl4a