Android和Python之间的不能说的小秘密

前言

看到这个标题,大家可能会认为就是Android运行python脚本,或者用python写app,这些用QPython和P4A就可以实现了。我在想既然C可以调用Python,那么Android能不能通过JNI去调用C里的方法,C再去调用Python方法,实现Android与Python交互呢?用最近很热的一个概念来说JNI就是个壳。(本文假设大家有JNI开发基础)

想法

由于需求很明确了,所以整体流程大概就是这样。

Android和Python之见的小秘密

交互流程

为什么要用python

  1. 首先看下我们为什么要在Android里需要使用Python,我认为主要有一下几个优点

Android和Python之见的小秘密

而Python只需要一句话就可以print出来

print ("hello world")

2.上手快,按网友所说,只需要读完Python API就可以成为大神,实际体验确实如此,十分好上手,如果现在让我推荐一个没有学过编程的人学习一款脚本语言,我会推荐他学一下python。

3.前期开发效率高,正如前两个优点所说,代码简洁、上手快而且由于属于超高级语言,很多东西都封装好了,决定了他前期开发效率很高。

4.可移植性强,由于是解释性语言,只需要有解释器,他可以运行在任何平台。

5.拓展性强,C/JAVA都有接口可以调用到Python,Python也可以调用到C,对Python进项拓展。

6.丰富的库,由于超高级语言,封装了很多方法,而且好多大牛对其开发了库。

当然还有几个缺点必须要强调一下。

  1. 强制缩进,代码简洁是把双刃剑,由于缩进所以简洁,而又由于缩进导致无法自动格式化代码,而且代码块的分割都是靠缩进,这时可能会造成混乱。

  2. 运行速度相对较慢,当然这个对相对C这种接近底层的语言来说的,Python在运行时先解析,再运行,而且由于高层语言相比底层语言都会慢那么一点。

  3. 版本兼容性较差,这个体现最明显的就是Python3和Python2,Python3不向下兼容更

Python视频、源码、资料加群857662006免费获取

Python C

Python C是C语言调用Python的一组API,通过它我们可以调用到Python方法。

Python C开发步骤

  1. 引入头文件Python.h;

  2. 初始化python(Py_Initialize();)

  3. 引入模块(pModule = PyImport_Import("pythoncode");)

  4. 获取模块中的函数(PyObject_GetAttrString(pModule, "hello");

  5. 调用获取的函数(PyEval_CallObject(pFunction, NULL);

  6. 释放python(Py_Finalize();)

对应的代码如下:

Android和Python之见的小秘密

当然,直接运行这段代码会报错,因为Python.h找不到还有相应的lib找不到,这里强烈建议使用mac或者Linux开发!!!填坑效率会比Windows高好多。具体怎么样处理这里先不说,如果实在需要,留言给我,我会另开一篇博文,毕竟这里是讲Android调用python的,而这个是在桌面环境下C调用Python的,而且百度也很多。

JNI Python C

当我成功使用C语言调用Python之后,我着手在JNI开发里调用Python,Python文件放在assets中 。

但是在开发过程中遇到了以下几个问题:

  1. 头文件找不到(Python.h)

  2. 没有移动平台的python.so

  3. 兼容性

  4. 找不到.py文件

接下来一个一个填坑。

头文件找不到(Python.h)

在MK文件中添加引用,

include $(CLEAR_VARS)

这段代码其实也把下一个问题解决了。

另外我们刚项目开始的时候可能为了开发方便,会在gradle中配置JNI资源文件夹路径,可是这导致了run project的时候AS也会对其中的C文件进行语法检查,这样由于没有外部头文件依赖,编译不会通过,所以我们需要在gradle中把JNI资源文件夹删了,用[]代替

sourceSets.main {

当我们编译成功SO库之后,C文件在运行中并不会被调用,而是调用编译为.so的文件中的方法。

没有移动平台的python.so

想要运行Python必须要有解释器,Android本身没有带,所以我们需要在程序中内嵌一个解释器,可是苦于找不到合适的so库,曾把P4A的python编译了一次,可是版本兼容性差,可用性不高。直到找到了Crystax NDK,它在10.3之后已经开始支持python for Android了,而且这个NDK资源包还填了几乎所有Android调用python的坑,包括第一个找不到头文件的问题,兼容的问题。在MK文件中,我们还需要加一段代码,编译crystax so库。

include $(CLEAR_VARS)

兼容性

Android目前有7个常见平台需要适配,其余的都没问题,只有X86和X86_64的有问题,推测crystax NDK Windows还没完善,因为mac下是可以直接编译的,所以有关编译的东西最好用Linux和Mac,Windows下我删了一个头文件,就可以运行了,没有发现异常。具体哪个我忘了,不过运行时报错哪个就去相应的文件里把头文件依赖删了就行,就一个。

然后生成7个平台的so库只需要在Application.mk中添加以下代码即可(APP_PLATFORM看个人调节):

APP_PLATFORM := android-19APP_ABI := armeabi-v7a armeabi mips mips64 arm64-v8a x86 x86_64

找不到.py文件

不知道什么原因,assets文件夹里的py文件获取不到,似乎是不能识别asset路径?求大神告知。解决方法就是把assets文件夹里的文件复制到设备的data文件夹里,再进行初始化。

Android和Python之见的小秘密

Android和Python之见的小秘密

JNI C代码:

Android和Python之见的小秘密

Python方面就是个简单的hello函数,返回“hello”字符串。

优化

当我把上述问题一一解决之后,终于见到之前写的python代码里返回的hello语句了。可由此也出现了一个问题,当我调用Python方法的时候,必须先引入模块,再引入方法,而且当我们需要添加Python方法的时候,我们还要去写重复的调用方法,只是换个方法名,而且需要再次编译各平台so库,我就想有没有一种方法可以只修改Python方法和java调用方法,而不去动C方法呢。

修改后的流程图如下:

Android和Python之见的小秘密

优化后流程

Python端增加一个路由方法,再写一个函数字典,把所有方法都加到字典里,C里调用的就是这个路由方法,java端调用的时候传入json里面包含了所需python方法,当json传入python中路由方法之后,自动匹配到相应的方法,每次添加新的方法只需要在python中添加字典已经方法,java调用时传入新的方法即可。

Python路由方法:

def router(args):

Python函数字典:

 
routes = { 'hello': hello, 'add': add, 'mul': mul,

JNI C调用python方法:

 
JNIEXPORT jstring JNICALL Java_com_jcmels_liba_pysayhello_PyBridge_call

java调用:

 
json.put("function", "hello");

后记

到此,Android call Python就基本完成了,调用第三方库的话只需要把ctype文件(Crystax文件夹中的sourcespython.5libs对应平台modules_ctypes.so)放到assets文件夹中就可以通过cdll.LoadLibrary来调用第三方库了。

在此感谢joaoventura大神的指导!

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Android Studio和Python可以结合使用来进行Android应用的开发。在Android Studio中使用Python需要导入相关的类和配置一些设置。首先,需要导入chaquopy的相关类,如com.chaquo.python.Kwarg、com.chaquo.python.PyObject、com.chaquo.python.android.AndroidPlatform和com.chaquo.python.Python。\[1\]然后,在配置步骤完成后,在src/main目录下创建一个名为"python"的文件夹,并在其中创建一个Python文件,可以在Android Studio中编写Python代码。和其他Python IDE一样,可以使用内置库,但通常需要使用第三方库。在Android Studio中,安装第三方库的方法与使用pip命令有所不同。可以在app/build.gradle文件中添加一些代码来配置Python环境,如指定Python路径和安装第三方库。\[2\]\[3\]这样就可以在Android Studio中使用Python来开发Android应用了。 #### 引用[.reference_title] - *1* *3* [Android-Studio与Python环境配置](https://blog.csdn.net/qq_55172460/article/details/126210910)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Android studio中编写Python代码-2](https://blog.csdn.net/weixin_29846499/article/details/116262692)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值