android开发中调用python代码(带参数)

android开发主要用到的是java代码,但是当开发涉及到一些算法时,往往用python可以提高软件的运行速度,也更加便捷,这里分享自己项目调用python代码的方式,主要有以下几个步骤(个人方法,欢迎指教):

1:配置调用环境

2:创建一个pythonHelper类用于搭建一个传参的桥梁:

3:拿到python文件,python代码中必须包含所需要调用的方法,参数和返回值必须对应好。否则会报空指针错误。

4:因为配置好了环境,再编写一段python环境下的代码来完成调用。

5:java中调用

第一步代码如下:(这里用的版本是python3.4版本)

private void loadPyFiles(File appFile, String appLib) {
        File pyLibFile = new File(appFile, "python3.4.zip");
        if (!pyLibFile.exists()) {
            copyFileOfAssets(getApplicationContext(), "python3.4.zip");
            copyFileOfAssets(getApplicationContext(), "_struct.cpython-34m.so");
            copyFileOfAssets(getApplicationContext(), "binascii.cpython-34m.so");
            copyFileOfAssets(getApplicationContext(), "time.cpython-34m.so");
            copyFileOfAssets(getApplicationContext(), "zlib.cpython-34m.so");
        }

        copyFileOfAssets(getApplicationContext(), "code_test.py");
        // copyFileOfAssets(getApplicationContext(), "MTool.py");
        // copyFileOfAssets(getApplicationContext(), "cardCombine_2.py");
        copyFileOfAssets(getApplicationContext(), "pro_num_3.py");

        copyFileOfAssets(getApplicationContext(), "penghu.py");
        copyFileOfAssets(getApplicationContext(), "PengHu_Main.py");

        System.loadLibrary("python3.4m");

        StarCoreFactoryPath.StarCoreCoreLibraryPath = appLib;
        StarCoreFactoryPath.StarCoreShareLibraryPath = appLib;
        StarCoreFactoryPath.StarCoreOperationPath = appFile.getPath();

        StarCoreFactory starFactory = StarCoreFactory.GetFactory();
        mStarService = starFactory._InitSimple("test", "123", 0, 0);
        mStarSrvGroup = (StarSrvGroupClass) mStarService._Get("_ServiceGroup");
        mStarService._CheckPassword(false);

        mStarSrvGroup._InitRaw("python34", mStarService);
        mStarPython = mStarService._ImportRawContext("python", "", false, "");
        mStarPython._Call("import", "sys");
        StarObjectClass pythonSys = mStarPython._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());
    }

    private void copyFileOfAssets(Context ctx, String name) {
        File outfile = new File(ctx.getFilesDir(), name);
        BufferedOutputStream mOutStream = null;
        BufferedInputStream mInStream = null;
        byte[] mBuffer = new byte[16 * 1024];
        int readLen = 0;
        try {
            mOutStream = new BufferedOutputStream(new FileOutputStream(outfile));
            mInStream = new BufferedInputStream(ctx.getAssets().open(name));
            while ((readLen = mInStream.read(mBuffer)) != -1) {
                mOutStream.write(mBuffer, 0, readLen);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (mOutStream != null) {
                    mOutStream.close();
                }
                if (mInStream != null) {
                    mInStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void do_python_cc(int[] cards, int tag) {
        if (isPyLoaded) {
            mStarService._DoFile("python", mAppFilePath + "/pro_num_3.py", "");
            mStarService._DoFile("python", mAppFilePath + "/code_test.py", "");
            mStarPython._Set("JavaClass", Log.class);
            PythonHelper.setDataArr(cards, tag);
            mStarPython._Set("PythonHelper", PythonHelper.class);
            mStarPython._Call("python_cc");
        }
    }

第二步,创建pythonHelper类.(主要是要有get,set方法在后面调用,具体变量因项目而异,这里我直接根据自己项目贴代码,主要是将需要调用的参数拿到)

public class PythonHelper2 {
    public static int[] mCards;
    public static int mTag;public static int mTargetCard;
    public static int mType;/**
     * 
     * @param mCards 
     * @param mTag 0,1,2,3
     * @param mDangerCards
     * @param mOldCards
     * @param mTargetCard
     * @param type 1:CHI ,2:PENG
     * @param mCountPeng
     * @param mCountHu
     */
    public static void setCards(int[] mCards,int mTag,int[] mDangerCards,int[] mOldCards,int mTargetCard,int type){
        PythonHelper2.mCards = mCards;
        mCardsLength = mCards==null?0:mCards.length;
        PythonHelper2.mTag = mTag;
        PythonHelper2.mTargetCard = mTargetCard;
        PythonHelper2.mType = type;
    }
    
    public static int[] getMatchCards(int[] result){
        mMatchCards = result;
        return mMatchCards;
    }
}

第三步:拿到需要调用的python文件必须包含要调用的方法。(下面是

get_result方法,且参数类型和顺序,数量跟我们调用时一样

第四步;编写调用代码。(需要重新在python中得到参数,得到的方式数组和数值方式有差异,如果是数组需要重新遍历赋值。

python_java = Python_Main.Main_Founc();

def python_ph():
    python_log("python_java 0000");
    #1.input_list
    param_len = PythonHelper.mCardsLength;
    python_log("python_java 1111 mCards_len=%d"%(param_len));
    input_list = [];
    cards_index = 0;
    while(cards_index < param_len):
        val = PythonHelper.mCards[cards_index];
        input_list.append(val);
        cards_index = cards_index + 1;
    #2.tags
    tags=PythonHelper.mTag;
    #3.danger_poke
    param_len1 = PythonHelper.mDangerCardsLength;
    python_log("python_java 2222 mDangerCards_len=%d"%(param_len1));
    danger_poke=[];
    cards_index1 = 0;
    while(cards_index1 < param_len1):
        val = PythonHelper.mDangerCards[cards_index1];
        danger_poke.append(val);
        cards_index1 = cards_index1 + 1;
    #5.inter_poke
    inter_poke = PythonHelper.mTargetCard;
    #6.type
    type=PythonHelper.mType;
    #######
    try:
        python_cards = python_java.get_result(input_list,tags,danger_poke,inter_poke);
    except Exception as e:
        python_log("python error: "+str(e)+str(type(oldcards_no_peng)))
    ccLen = len(python_cards);
    python_log("python_java 6666 return cards size=%d"%(ccLen));
    PythonHelper.getMatchCards(python_cards);

第五步,java中调用

private void getResultByPython(int[] input_list, int tags, int inter_poke,
            int type,int[] dangerCards) {
        int[] dangerCards = PlayCardEngine2.getInstance().getTableSnap()
                .getVismDangerCards();if (isPyLoaded) {
            mStarService._DoFile("python", mAppFilePath + "/penghu.py", "");
            mStarService
                    ._DoFile("python", mAppFilePath + "/PengHu_Main.py", "");
            mStarPython._Set("JavaClass", Log.class);
            PythonHelper2.setCards(input_list, tags, dangerCards, oldCards,
                    inter_poke, type, count_Peng, count_Hu, times, throwCards, myAndNextThrowCards);
            mStarPython._Set("PythonHelper2", PythonHelper2.class);
            mStarPython._Call("python_penghu");
        } else {
            Log.d("getResultByPython", "isPyLoaded : " + isPyLoaded);
        }
    }

需要用到的包和so:_struct.cpython-34m.so          binascii.cpython-34m.so            python3.4.zip           time.cpython-34m.so          zlib.cpython-34m.so          (可以自行下载或者联系我)

因为项目中代码太多,我有做删减,所以以上代码会存在一些不齐全问题,但是关键的步骤是没错的。需要根据实际情况做修改。

本人也是萌新,欢迎互相探讨交流。

谢谢!!!!

posted @ 2019-02-27 10:23  小牧头  阅读(13918)  评论(2编辑  收藏  举报