Android中调用.py文件

1、开发环境

Android Studio 3.2

2、准备

下载最新的CLE for Android

CLE网站

下载之后解压,将示例工程中的几个starcore_android_rXXX.jar拷贝到Android Studio工程App->libs文件夹下,将其他文件也按照正常位置放好,如下图所示:

如图所示

然后在libs的文件右键,Add As Library,或者直接在app的bulid.gradle添加编译选项:

implementation files('libs/starcore_android_r2.51.jar')

implementation files('libs/starcore_android_r3.0.jar')

然后编辑内部的三个py文件,calljava、text.py(本来应该是test.py的,打错了,将错就错)、py_code.py。就是运行一个demo所以写两个验证一下就好:

text.py:

def add(x,y) :
    return x+y

py_code.py:

import time

def get_time():
    return time.time()

calljava.py:

import imp  #test load path

def log(content):
    JavaClass.d("formPython",content)

log("Hello Android,form python")

3、在Java中调用

现在代码和工具都已经准备好了,就可以在Android中尝试调用了:

public StarSrvGroupClass SrvGroup;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final File appFile = getFilesDir();  /*-- /data/data/packageName/files --*/
        final String appLib = getApplicationInfo().nativeLibraryDir;

        AsyncTask.execute(new Runnable() {

            @Override
            public void run() {
                loadPy(appFile,appLib);
            }
        });
    }

    void loadPy(File appFile,String appLib){
        //拷贝Python相关环境
        File pythonLibFile = new File(appFile, "python3.4.zip");
        if (!pythonLibFile.exists()) {
            copyFile(this, "python3.4.zip");
            copyFile(this, "_struct.cpython-34m.so");
            copyFile(this, "binascii.cpython-34m.so");
            copyFile(this, "time.cpython-34m.so");
            copyFile(this, "zlib.cpython-34m.so");
        }

        // 拷贝Python 代码
        copyFile(this, "calljava.py");
        copyFile(this, "test.py");

        try {
            // 加载Python解释器
            System.load(appLib + File.separator + "libpython3.4m.so");

            // 除了将代码直接拷贝,还支持将代码压缩为zip包,通过Install方法解压到指定路径
            InputStream dataSource = getAssets().open("py_code.zip");
            StarCoreFactoryPath.Install(dataSource, appFile.getPath(),true );
        } catch (Exception e) {
            e.printStackTrace();
        }

        /*----init starcore----*/
        StarCoreFactoryPath.StarCoreCoreLibraryPath = appLib;
        StarCoreFactoryPath.StarCoreShareLibraryPath = appLib;
        StarCoreFactoryPath.StarCoreOperationPath = appFile.getPath();

        StarCoreFactory starcore = StarCoreFactory.GetFactory();
        StarServiceClass Service = starcore._InitSimple("test", "123", 0, 0);
        SrvGroup = (StarSrvGroupClass) Service._Get("_ServiceGroup");
        Service._CheckPassword(false);

        /*----run python code----*/
        SrvGroup._InitRaw("python34", Service);
        StarObjectClass python = Service._ImportRawContext("python", "", false, "");
        // 设置Python模块加载路径
        python._Call("import", "sys");
        StarObjectClass pythonSys = python._GetObject("sys");
        StarObjectClass pythonPath = (StarObjectClass) pythonSys._Get("path");
        pythonPath._Call("insert", 0, appFile.getPath()+ File.separator +"python3.4.zip");
        pythonPath._Call("insert", 0, appLib);
        pythonPath._Call("insert", 0, appFile.getPath());

        //调用Python代码
        Service._DoFile("python", appFile.getPath() + "/py_code.py", "");
        long time = python._Calllong("get_time");
        Log.d("python", "form python time="+time);

        Service._DoFile("python", appFile.getPath() + "/text.py", "");
        int result = python._Callint("add", 5, 2);
        Log.d("python", "result="+result);

        python._Set("JavaClass", Log.class);
        Service._DoFile("python", appFile.getPath() + "/calljava.py", "");
    }

    private void copyFile(Context c, String Name) {
        File outfile = new File(c.getFilesDir(), Name);
        BufferedOutputStream outStream = null;
        BufferedInputStream inStream = null;

        try {
            outStream = new BufferedOutputStream(new FileOutputStream(outfile));
            inStream = new BufferedInputStream(c.getAssets().open(Name));

            byte[] buffer = new byte[1024 * 10];
            int readLen = 0;
            while ((readLen = inStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, readLen);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inStream != null) inStream.close();
                if (outStream != null) outStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

这时去查看log,会有三个tag为python的输出,就是调用三个python文件的结果