- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
翻译自 https://proandroiddev.com/chaquopy-using-python-in-android-apps-dd5177c9ab6b 。
欢迎通过 我的Blog 访问此文章. 。
Python在开发者社区中时最受欢迎的语言之一, 因为其简单,健壮并且有着庞大的软件生态使其可以在多个领域发挥作用. 类似NumPy和SciPy这样的包允许你在项目中使用高等数学计算, 而这样的计算在其它的语言中是无法简单实现的. 那么如果将Python引入到Android应用中又会带来什么样效果呢?
Chaquopy 是一个可以帮助开发者通过Java/Kotlin在Android平台中运行Python脚本的框架. 和其它跨语言库不同, 它不再有NDK依赖的烦恼, 也不需要native code [1] , 并且安装也十分的简单. 在这篇文件中, 我们将探索Chaquopy, 并通过Kotlin来进行构建和使用. 。
和大多数跨语言接口工作原理一样, Python和Android都有着C/C++的血统, 使其可以通过中间件来进行通信. Android的NDK允许开发者使用通过C/C++编写的本地库, 来帮助Android应用获得更好的图形和科学计算效果. 。
Chaquopy使用CPython, 一个通过C来实现的Python实现. 不同于一般的误解, Python并不是一个纯粹的解释性语言. Python的源码最开始会被构建为可以被CPython执行的特殊字节码. 当然, CPython只是Python的几种解释器之一, 其它的还有PyPy, IronPython, Jython等等. 。
Chaquopy通过Android NDK工具链来构建CPython, CPython在项目构建的时候通过Chaquopy Gradle插件从Maven仓库中心进行下载, 在这个过程中用户并不需要下载NDK. 它还下载Chaquopy运行支持通过JNI将Java/Kotlin和Python连接起来. 。
同时, 我们还需要Python包管理工具 pip , 它可以下载为解释器下载包. 像 NumPy 和 SciPy 这样的受欢迎的包可以通过原生代码执行高密集的CPU计算, 我们需要事先安装这些包. 因此, Chaquopy团队维护了自己的存储库,其中包含专门为Android的ARM架构构建的本地软件包. 这些软件包的维护者不会为Android平台构建他们的本地代码,因为用户数量较少,因此Chaquopy团队会针对Android平台构建它们并通过自己的存储库进行发布. 。
对于纯粹的Python包, 不需要额外的构建并且Chaquopy可以直接运行这些.从更宏观来看, Chaquopy包含了三个主要的组件. 。
在新/现有的Android项目中添加Chaquopy, project级的 build.gradle 文件的顶部, 我们定义项目的plugin并且添加Chaquopy的Gradle插件. 。
plugins {
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
id 'com.chaquo.python' version '13.0.0' apply false
}
下一步, 我们在module级的 build.gradle 文件中添加Chaquopy plugin和指定ABI规则.
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.chaquo.python'
}
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a" //, "arm64-v8a", "x86", "x86_64"
}
}
...
}
正如官方文档提及的, Python解释器是使用Android NDK来构建的本机组件,NDK为指定的版本构建原生代码, 比如like arm,x86或x86_64. 不同的设备支持不同的架构. 所以我们只能包含特定版本的Python解释器, 而不是为所有架构都进行构建, 因为这会增加应用程序的大小. Android官方文档 中是这么说的.
构建系统的默认行为是将每个ABI的二进制文件包括在单个APK也称为胖 APK)内. 与仅包含单个ABI的二进制文件的APK相比,胖APK要大得多, 要权衡的是兼容性更广,但APK更大. 强烈建议您利用app bundle和APK拆分减小 APK的大小,同时仍保持最大限度的设备兼容性. 。
下一步, 我们将配置Python构建版本, 我们可以通过修改module级 build.gradle 文件来指定版本. 。
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.chaquo.python'
}
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a" //, "arm64-v8a", "x86", "x86_64"
}
python {
version "3.10"
}
}
...
}
不同的Chaquopy支持不同的Python版本有着不同的最小API需要. 通过 这个表 可以查找到你需要匹配的版本. 下一步, 我们指定在Python解释器需要的包的版本. 。
defaultConfig {
python {
pip {
// A requirement specifier, with or without a version number:
install "scipy"
install "requests==2.24.0"
// An sdist or wheel filename, relative to the project directory:
install "MyPackage-1.2.3-py2.py3-none-any.whl"
// A directory containing a setup.py, relative to the project
// directory (must contain at least one slash):
install "./MyPackage"
// "-r"` followed by a requirements filename, relative to the
// project directory:
install "-r", "requirements.txt"
}
}
}
这是在Chaquopy中安装包的几种不同方法. 它可以是具有特定版本的包名, 也可以是自定义包或者 requirement.txt 包列表. 。
在Python中,我们使用属于Python模块的函数或者数据成员, 一个Python模块包含.py文件. 要使用任何Python模块中的成员. 第一步是将Python源代码放入 <project>/app/src/main/python 文件夹中. 。
# Contents of my_module.py
import numpy as np
def get_exec_details():
return __file__
def sumOp( nums ):
return sum( nums )
def powOp( a , x ):
return a**x
def npMatrixSum( m , n ):
mat = np.ones( ( m , n ) )
mat_sum = np.sum( mat , axis=1 )
return mat_sum
class Operations:
num_ops = 2
def meanOp( self , nums ):
return sum( nums ) / len( nums )
def maxOp( self , nums ):
return max( nums )
nums_len = 10
nums_len_str = "ten"
ops = Operations()
为了使用 my_module 中的成员, 我们需要使用 Python.getModule 方法传递模块的名称. 在这之前, 我们需要运行 Python 在应用中被允许, 这可以在Application的onCreate方法中执行.
class App : Application() {
override fun onCreate() {
super.onCreate()
if( !Python.isStarted() ) {
Python.start( AndroidPlatform( this ) )
}
}
}
将 App 添加到 AndroidManifest.xml 。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".App"
...
</application>
</manifest>
那么在 MainActivity 中, 我们就可以使用 Python.getInstance (否则的话会出现 PyException 异常).
val py = Python.getInstance()
val module = py.getModule( "my_module" )
为了使用数据成员, 像 my_module.py 中的 nums_len .
val numsLength = module[ "nums_len" ]?.toInt()
println( "Nums Length is $numsLength" )
Nums Length is 10
访问对象 ops 类中的属性 。
val ops = module[ "ops" ]!!
println( "Operations: $ops" )
println( "num_ops : ${ ops[ "num_ops" ] }" )
println( "mean func : ${ ops[ "meanOp" ] }" )
Operations: <my_module.Operations object at 0xb9339ce8>
num_ops : 2
mean func : <bound method Operations.mean of <my_module.Operations object at 0xb9339ce8>>
由于Python中的函数是对象, 因此允许将函数作为模块的值进行访问.然后,我们使用 PyObject.call 方法来向函数传递参数并获取结果(如果函数返回一个值). 。
val sumFunc = module[ "sumOp" ]
val sum = sumFunc?.call( intArrayOf( 12 , 25 , 32 ) )
val powFun = module[ "powOp" ]
val pow = powFun?.call( 5 , 2 )
println( "Sum: $sum" )
println( "Pow: $pow" )
Sum: 69
Pow: 25
要从 ops 对象访问成员函数, 。
val meanFunc = ops[ "meanOp" ]
val mean = meanFunc?.call( intArrayOf( 23 , 45 , 12 , 91 ) )
println( "Mean: $mean" )
// OR
val mean = ops.callAttr( "meanOp" , intArrayOf( 23 , 45 , 12 , 91 ) )
println( "Mean: $mean" )
Mean: 42.75
这是一个示例, 其中Python函数使用 numpy 并返回类型为 np.ndarray 的结果 。
# my_module.py
import numpy as np
def npMatrixSum( m , n ):
mat = np.ones( ( m , n ) )
mat_sum = np.sum( mat , axis=1 )
return mat_sum
val npSumFunc = module[ "npMatrixSum" ]
val output = npSumFunc?.call( 2 , 3 )
// OR
val output = module.callAttr( "npMatrixSum" , 2 , 3 )
println( "Output: $output" )
println( "Output shape: ${output!![ "shape" ] }")
Output: [3. 3.]
Output shape: (2,)
希望我为您的Android开发工具箱添加了一个新工具! Chaquopy是一个非常好用的工具, 具有清晰明了的语法和无需费心安装的优点.你可以在下一个Android项目中使用它.继续学习,祝您度过愉快的一天.
完成代码可以访问 我的GitHub 。
没能完全理解这里的native code具体代指的是什么, 但是我觉得这里的意思是不需要在Android应用中引入C/C++代码, 也就是说不需要在Android应用中引入NDK. ↩︎ 。
最后此篇关于在Android应用中通过Chaquopy使用Python的文章就讲到这里了,如果你想了解更多关于在Android应用中通过Chaquopy使用Python的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在使用这个文件来检查 Android 应用程序中文档的语法,但它在语言工具中给了我错误消息。我正在使用 tool = language_check.LanguageTool('en-US')检查语
当使用 chaquopy for android 时,从 java 调用模块不会运行 __init__ 方法。 PyObject utilModule = py.getModule("utils.Ut
我该怎么做? 我看到你的帖子说你可以将 java 对象传递给 Python 方法,但这不适用于 numpy 数组和 TensorFlow 张量。以下以及其各种变体是我尝试过的,但没有成功。 doubl
如何调用我使用 Chaquopy 编写的函数? 我使用了文档中的示例,效果很好。我可以使用 Python 将文本放在标签上。然后我创建了一个按钮并想调用我的函数(例如,my_func): from d
我想使用 Chaquopy 读取文件。在出现诸如“PermissionError”之类的错误后,我在 Python Idle 和 Chaquopy 中编写了相同的代码: Idle 中的这段代码在输出中
我有一个 Android 相机应用程序和一个单独的 Python 图像处理管道,我想使用 Chaquopy 与该应用程序集成。然而,python 代码本身很大,并且依赖于大约 50 个模块,例如 te
我正在尝试在运行计算机视觉 python 脚本的 Android 应用程序中引用两个文件。 按照此处的说明操作:https://chaquo.com/chaquopy/doc/current/andr
因此,从文档中我想出了如何将文件“硬编码”到 android studio(基本上在 androidstudioprojects 目录中)并且可以从我的 python 脚本成功访问它们。 (使用 jo
android 构建成功,但在运行时抛出错误。 so和python文件路径为app\src\main\python。 1.so文件路径改成app\src\main\jniLibs\arm64-v8a或
我已将 Chaquopy 实现到我的 Android 应用程序中,以利用 Python 中预先训练的神经网络模型。 尝试调用python代码时遇到; “com.chaquo.python.PyExce
我正在尝试使用 android 上的 chaquopy 工具实时下载 nltk 所需的软件包。 我正在尝试将模型下载到特定的数据目录中,如下所示: from android.os import Bun
我目前正在尝试找出如何从 Python 模块更改 MainActivity(UI 是用 Java 编写的)中的 TextView 的文本。我知道我必须以某种方式将我的 mainactivity 传递给
所以,我对 chaquopy 还很陌生,想知道是否有新生成的(即:在应用程序运行时编写的构建后).py 文件来运行? 我的意思是:假设我将 textEdit View 的内容保存到一个名为“newFi
我正在尝试使用 Chaquopy 将计算机视觉应用程序移植到 Android。当我尝试运行我的脚本时,以下行出现以下错误: cv2.waitKey(100) 打印到嵌入式 python 控制台的错误是
如何将多个列表、值等从我的 Python 脚本返回到 Java 而不会以单个对象结束?现在,我以一个包含两个返回值的 PyObject 结束,但我还没有想出如何在 Java 中再次将它们分开。 pyt
我正在使用 chaquopy在 android 中运行 python 的演示。 (取自 GitHub https://github.com/ericdecanini/HelloChaquopy ) 我
我目前正在使用 Android Studio 和 BeautifulSoup 制作一个网络抓取应用程序。我如何实现 from bs4 import BeautifulSoup 像在 Python 中一
我正在构建一个集成了 python 的 android 应用程序。我使用 chaquopy 将 python 与 android 集成。我已经为它安装了 TensorFlow 2.2 和 python
我在 android 应用程序中使用 python 作为一些科学程序的后端代码。为此,我正在使用 Chaquopy 插件。访问存储在“app/src/main/python/”的文本文件时,我发现错误
我尝试在 Android 应用程序中使用原型(prototype) python 代码,我发现了 Chaquopy作为一个可能的库。 文档有点稀疏,所以我想澄清一下:我可以使用 Chaquopy 在
我是一名优秀的程序员,十分优秀!