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 (可以自行下载或者联系我)
因为项目中代码太多,我有做删减,所以以上代码会存在一些不齐全问题,但是关键的步骤是没错的。需要根据实际情况做修改。
本人也是萌新,欢迎互相探讨交流。
谢谢!!!!