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 (可以自行下載或者聯系我)
因為項目中代碼太多,我有做刪減,所以以上代碼會存在一些不齊全問題,但是關鍵的步驟是沒錯的。需要根據實際情況做修改。
本人也是萌新,歡迎互相探討交流。
謝謝!!!!