Android Java代码调用Python代码

一,通过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

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ang_qq_252390816

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值