android调用python脚本

android 专栏收录该内容
67 篇文章 0 订阅

前言

文章可以帮你解决android下调用python方法获取返回值,往python函数中传参等。开发环境基于Android studio.

详细介绍

一.环境准备

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

http://www.srplab.com/cn/files/products.html

你可能会遇到的问题

1:注意so版本;版本都要一致,从开发包里复制粘贴;
2:注意so引入路径;as和ec是有区别的;

  • 拷贝 starcore_android_rX.X.jar的arm64-v8a目录内容到工程的libs目录
  • 拷贝starcore_android_rX.X.jar的到starcore_android_r3.7.dex、starcore_android_r3.7.jar到libs目录

如下图:

libs的和assets里面的so;

二、编写Python代码

test.py文件内容如下:

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

calljava.py内容如下:

import imp  #test load path

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

log("Hello Android,form python")

py_code.py内容如下:

import time

def get_time():
    return time.time()

将py_code.py压缩为py_code.zip文件。将编写的Python源码放入Android 工程的assets目录,其中还要包含一些Python需要的环境及标准库(android.python.3.7.0里面arm64-v8a\lib-dynload中找到对应的so库),见下图

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

package com.cootf.mytest;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.srplab.www.starcore.StarCoreFactory;
import com.srplab.www.starcore.StarCoreFactoryPath;
import com.srplab.www.starcore.StarObjectClass;
import com.srplab.www.starcore.StarServiceClass;
import com.srplab.www.starcore.StarSrvGroupClass;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();
    private Subscription mSubscription;
    ActivityManager mAm;
    public StarSrvGroupClass SrvGroup;
    private StarServiceClass Service;
    private StarCoreFactory starcore;
    private StarObjectClass python;
    private File appFile ;
    private String appLib ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate");
        setContentView(R.layout.activity_main);
        mAm = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        Iterator<ActivityManager.RunningTaskInfo> iter =                mAm.getRunningTasks(100).iterator();
        appFile = getApplicationContext().getFilesDir();  /*-- /data/data/packageName/files --*/
        appLib = getApplicationInfo().nativeLibraryDir;
        loadPy();
    }

    void loadPy(){
        loadPyEnviroment();
        initCle();
        runPy();
    }

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

        // 拷贝Python 代码
        copyFile(this, "calljava.py");
        //copyFileFromSdcard(this, "test.py"); //验证读取sdcard里面的文件也可以
        copyFile(this, "test.py");

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

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

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

        starcore = StarCoreFactory.GetFactory();
        starcore._SRPLock();
        Log.d(TAG,"zjy startcore:"+starcore);
          SrvGroup = starcore._GetSrvGroup(0);
        Log.d(TAG,"zjy SrvGroup:"+SrvGroup);
        Service = SrvGroup._GetService("test","123");
        Log.d(TAG,"zjy Service:"+Service);
        if( Service == null ){ // the service has not been initialized
            Log.d(TAG,"zjy Service is null");
            Service = starcore._InitSimple("test", "123", 0, 0);
        }else{
              Log.d(TAG,"zjy SrvGroup:"+SrvGroup);
             Service._CheckPassword(false);
        }
        Service._CheckPassword(false);
        /*----run python code----*/
        SrvGroup._InitRaw("python37", Service); // this place
        python = Service._ImportRawContext("python", "", false, "");
        StarObjectClass model = python._GetObject("pd");
        python._Call("import", "sys");
        StarObjectClass pythonSys = python._GetObject("sys");
        StarObjectClass pythonPath = (StarObjectClass) pythonSys._Get("path");
        pythonPath._Call("insert", 0, appFile.getPath()+ File.separator +"python3.7.zip");
        pythonPath._Call("insert", 0, appLib);
        pythonPath._Call("insert", 0, appFile.getPath());
        starcore._SRPUnLock();
    }
  private void runPy() {
        //调用Python代码
        Service._DoFile("python", appFile.getPath() + "/py_code.py", "");
        long time = python._Calllong("get_time");
        Log.d(TAG, "form python time="+time);

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

        python._Set("JavaClass", Log.class);
        Service._DoFile("python", appFile.getPath() + "/calljava.py", "");
    }
private void copyFile(Activity 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();
            }
        }
    }
private void copyFileFromSdcard(Activity c, String Name) {
        File outfile = new File(c.getFilesDir(), Name);
        BufferedOutputStream outStream = null;
        BufferedInputStream inStream = null;
        InputStream  redis = null;

        try {
            String sdpath =       Environment.getExternalStorageDirectory().getAbsolutePath();
            String filePath = sdpath +File.separator + Name;
            redis = new FileInputStream(new File(filePath));
            outStream = new BufferedOutputStream(new FileOutputStream(outfile));
            inStream = new BufferedInputStream(redis);

            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();
            }
        }
    }
 @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG,"onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG,"onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG,"onPause");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG,"onDestroy X");
        starcore._ModuleClear();
//        starcore._ModuleExit();
        Log.d(TAG,"onDestroy E");
    }
}

    

app的 build.gradle配置:

apply plugin: 'com.android.application'
android {
    compileSdkVersion 25
    defaultConfig {
        applicationId "com.cootf.mytest"
        minSdkVersion 14
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    // jni配置
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

 

 

 

  • 1
    点赞
  • 7
    评论
  • 22
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值