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