Android 平台的Python——CLE方案实现(三)

来源:互联网 发布:网络大学报名流程 编辑:程序博客网 时间:2024/05/21 04:21

CLE(Common Language Extension)公共语言拓展
官网:http://www.srplab.com/cn/index.html
来自官网的简介:
CLE中间件支持多脚本语言混合编程。c/c++, lua, python, c#, ruby, java等语言可以通过CLE中间件直接使用其它语言中的类,函数,变量或者模块, 使得现有的功能库或者模块可以很容易的应用到其它编程语言中。开发者可以使用熟悉的语言编写功能库,然后在其它语言开发的应用中使用。CLE非常简单,其执行体仅为一个核心共享库和对应于每个脚本语言接口的共享库.

我们建议开发人员使用脚本语言编写主逻辑,并使用平台相关的语言开发GUI或设备特定部分。这样不仅可以保证应用程序的可移植性,而且还利用了平台SDK的优势。使用脚本语言可能会导致安装包的大小增加, 性能略有下降,但随着硬件性能提高和存储增加, 这些将不成为问题

在Android中通过CLE框架,实现与Python交互

1、环境准备

在官网下载最新的CLE for Android 开发包,其中包含示例工程和API文档。解压开发包,拷贝如下文件

  • 拷贝 starcore_android_rX.X.jar到工程的libs目录
  • 拷贝 libstar_java.so、libstarcore.so、libpython3.4m.so和libstar_python34.so到libs目录

这里写图片描述

2、编写Python代码

text.py

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

calljava.py

import imp  #test load pathdef log(content):    JavaClass.d("formPython",content)log("Hello Android,form python")

py_code.py

import timedef get_time():    return time.time()

将py_code.py压缩为py_code.zip文件。将编写的Python源码放入Android 工程的assets目录,其中还要包含一些Python需要的环境及标准库,见下图

这里写图片描述

3、编写Android相关代码,初始化CLE并调用Python

public class MainActivity extends Activity {    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("", "form python time="+time);        Service._DoFile("python", appFile.getPath() + "/test.py", "");        int result = python._Callint("add", 5, 2);        Log.d("", "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();            }        }    }}

以上代码即完成了Java与Python的互相调用,其中python._Set(“JavaClass”, Log.class)一句,指将一个java类设置给Python,变成Python类,第一个参数指定在Python中的类名,此处随意起了一个类名JavaClass,该类可直接在Python中使用,如上将Android的日志输出类设置给Python使用

关于CLE的相关原理,可进入官网了解,更多详细用法,见CLE文档

阅读全文
1 0
原创粉丝点击