目录
技术背景
kivy的安装
kivy的helloworld
选择使用虚拟环境的原因
apk构建环境配置
安装buildozer
buildozer的基本使用
构建问题处理
dpkg的依赖安装
基于docker的buildozer方案
adb日志定位apk问题
kivy的字符串计算器案例
kivy按钮实例
kivy文本框示例
核心:打包math仓库到app中
总结概要
版权声明
技术背景虽然现在苹果占据了很大一部分的市场,但是从销量数据来看,安卓还是占据了人口的高地。这里我们介绍一个用python的kivy+buildozer来进行安卓APP开发的简单教程,从整个过程中来看,环境部署这一块所需的工作量是非常大的,可能这就是从0到1的困难?文末我们会总结出,哪一种方案是最容易的,希望能够对大家有所帮助。
kivy的安装官方推荐的方式是使用虚拟环境来进行安装和部署,关于虚拟环境的相关操作,在前面写过的一篇博客中有稍微详细一点的介绍,这里我们先给出操作步骤。假定我们已经在环境中用pip安装了virtualenv,那么我们先构建一个kivy的虚拟环境:
[dechin@dechin-manjarokivy]$virtualenvkivy_(dest=/home/dechin/projects/2021-python/kivy/kivy_venv,clear=False,no_vcs_ignore=False,global=False)seederFromAppData(download=False,pip=bundle,setuptools=bundle,wheel=bundle,via=copy,app_data_dir=/home/dechin/.local/share/virtualenv)addedseedpackages:pip==21.0.1,setuptools==54.1.2,wheel==0.36.2activatorsBashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
构建完成后会在当前目录下生成一个文件夹:
[dechin@dechin-manjarokivy]$ll总用量4drwxr-xr-x4dechindechin40964月322:00kivy_venv
我们可以用source./kivy_env/bin/activate的方式对虚拟环境进行激活,激活后每次执行系统操作指令,会在指令的最前端显示一个虚拟环境的标识,比如这里我们在虚拟环境中用pip来安装kivy:
(kivy_venv)[dechin@dechin-manjarokivy]$python3-mpipinstallkivy-i(22.2MB)|████████████████████████████████|22.2/sCollectingpygmentsDownloading(983kB)|████████████████████████████████|983kB688kB/sCollectingKivy-Garden=0.1.4Downloading(6.8kB)CollectingdocutilsDownloading(575kB)|████████████████████████████████|575kB912kB/sCollectingrequestsDownloading(61kB)|████████████████████████████████|61/sCollectingcertifi=2017.4.17Downloading(147kB)|████████████████████████████████|147kB726kB/sCollectingidna3,=2.5Downloading(58kB)|████████████████████████████████|58kB644kB/,=1.21.1Downloading(153kB)|████████████████████████████████|153kB564kB/sCollectingchardet5,=3.0.2Downloading(178kB)|████████████████████████████████|178kB827kB/sBuildingwheelsforcollectedpackages:Kivy-GardenBuildingwheelforKivy-Garden()doneCreatedwheelforKivy-Garden:filename=Kivy_=4532sha256=70dd6bf0a005868e9aca0710f7b717432bda7925c0fac236b99d2527ec112b78Storedindirectory:/home/dechin/.cache/pip/wheels/c9/d0/d4/2cb72931b74be8ce5fbee5ed87d66366f356a3161ea772d015SuccessfullybuiltKivy-GardenInstallingcollectedpackages:urllib3,idna,chardet,certifi,requests,pygments,Kivy-Garden,docutils,
为了加快安装,我们使用了腾讯的pip源。安装完成后,可以在已安装列表中看到刚才安装的kivy及其依赖组件:
(kivy_venv)[dechin@dechin-manjarokivy]$kivy的helloworld
配置好kivy的环境后,我们可以直接在电脑端测试python所编写的app实例,比如kivy的helloworld:
注意匹配版本号(App):defbuild(self):returnLabel(text='Helloworld')if__name__=='__main__':MyApp().run()
可以直接用python3kivy_hello_的指令来执行,执行结果如下图所示:
执行期间我们可以在屏幕上看到一系列的日志输出,在有报错问题的时候,查询执行日志是必须使用的定位手段:
[INFO][Logger]Recordlogin/home/dechin/.kivy/logs/kivy_21-04-03_1.txt[INFO][Kivy][INFO][Kivy]Installedat"/home/dechin/projects/2021-python/kivy/kivy_venv/lib//site-packages/kivy/__init__.py"[INFO][Python](default,Sep42020,07:30:14)[][INFO][Python]Interpreterat"/home/dechin/projects/2021-python/kivy/kivy_venv/bin/python3"[INFO][Factory]186symbolsloaded[INFO][Image]Providers:img_tex,img_dds,img_sdl2(img_pil,img_ffpyplayerignored)[INFO][Text]Provider:sdl2[INFO][Window]Provider:sdl2[INFO][GL]Usingthe"OpenGL"graphicssystem[INFO][GL]Backusedsdl2[INFO][GL]OpenGLversionb'4.6(CompatibilityProfile)'[INFO][GL]OpenGLvorb'Intel'[INFO][GL]OpenGLrererb'MesaIntel(R)UHDGraphics620(WHLGT2)'[INFO][GL]OpenGLparsedversion:4,6[INFO][GL]Shadingversionb'4.60'[INFO][GL]Texturemaxsize16384[INFO][GL]Texturemaxunits32[INFO][Window]autoaddsdl2inputprovider[INFO][Window]virtualkeyboardnotallowed,singlemode,notdocked[INFO][ProbeSysfs]devicematch:/dev/input/event16[INFO][MTD]Readeventfrom/dev/input/event16[INFO][Base]Startapplicationmainloop[INFO][GL]NPOTtexturesupportisavailable[WARNING][MTD]Unabletoopevice"/dev/input/event16".Pleaseensureyouhavetheappropriatepermissions.[INFO][Base]Leavingapplicationinprogress
到这里,我们的第一步工作就基本完成了,但是需要注意的是,这里我们的程序还是运行在电脑端的,我们需要将其打包成apk文件之后,才能在手机端运行。
选择使用虚拟环境的原因这里我们单独一个小章节,说明一下为什么官方推荐的使用方法很多都是使用虚拟环境,这个其实跟后面要介绍的apk打包有较大关系。我们在打包apk的过程中,如果有相关的python依赖包,都需要在配置文件中提前标识。这一点非常重要,最好是能够指定具体的版本号进行安装,否则会出现打包失败的问题,如果到了打包的阶段再去定位和解决此类问题,会非常的麻烦。
apk构建环境配置我们在本地采用了buildozer的方案来进行apk的构建,如果在本地其他环境依赖如jdk等都已经部署完毕,在虚拟环境里面直接安装buildozer是没有问题的。但是由于本地环境中依赖都比较缺乏,因此为了避免环境切换混乱,这里我们使用虚拟环境来展示安装和使用的基本方法,但是实际应用场景下,我们还是直接使用了本地的python3环境,而不是虚拟环境。
安装buildozer跟其他python库一样的,我们可以通过pip来对buildozer进行安装和管理:
(kivy_venv)[dechin@dechin-manjarokivy]$python3-mpipinstallbuildozer-i(77kB)|████████████████████████████████|77kB783kB/sCollectingshDownloading(40kB)|████████████████████████████████|40/sCollectingpexpectDownloading(59kB)|████████████████████████████████|59/sCollectingvirtualenvDownloading(7.2MB)|████████████████████████████████|7.2/sCollectingptyprocess=0.5Downloading(13kB)Collectingdistlib1,=0.3.1Downloading(335kB)|████████████████████████████████|335kB721kB/sCollectingsix2,=1.9.0Downloading(10kB)Collectingappdirs2,=1.4.3Downloading(9.6kB)Collectingfilelock4,=3.0.0Downloading(7.6kB)Installingcollectedpackages:six,ptyprocess,filelock,distlib,appdirs,virtualenv,sh,pexpect,
安装完成后,应该要在本地可以看到buildozer的安装位置:
(kivy_venv)[dechin@dechin-manjarokivy]$whichbuildozer/home/dechin/projects/2021-python/kivy/kivy_venv/bin/buildozerbuildozer的基本使用
从框架上来说,buildozer的使用方法其实只有两个步骤:先用init生成配置文件,然后使用buildozerdebug就可以构造一个apk文件了,如果顺利的话:)
(kivy_venv)[dechin@dechin-manjarokivy]$,readytocustomize!
按照流程第一步初始化完成后,当前的目录下会生成一个的配置文件,与其他软件所不一样的是,这个配置文件又臭又长,修改起来非常的不便,对新手极其不友好。但是,运气好的情况下也不需要去修改这个配置文件就可以成功构建apk。
(kivy_venv)[dechin@dechin-manjarokivy]$ll总用量24-rw-r--r--1dechindechin104894月322:17月322:06kivy_hello_月322:00kivy_venv
当你执行下面的指令,正常情况下麻烦才刚刚开始:
(kivy_venv)[dechin@dechin-manjarokivy]$buildozerandroiddebugdeployrunEnsurebuildlayoutCreatedirectory/home/dechin/.buildozer/cacheCreatedirectory/home/dechin/projects/2021-python/kivy/binCreatedirectory/home/dechin/.buildozer/android/platform/android/platformCreatedirectory/home/dechin/projects/2021-python/kivy/.buildozer/android//bin/sh:行1:dpkg:未找到命令-foundat/usr/bin/git-foundat/home/dechin/anaconda3/bin/cythonJavacompiler(javac)notfound,pleaseinstallit.
没有dpkg,没有jdk,在参考链接5里面还有人专门整理了各种可能猜到的坑,对这些环境有依赖,为何不能在文档中提前说明呢?这里还有一点需要注意的是,虽然buildozer官方提供了docker的解决方案,但是我们极其不推荐使用官方提供的docker解决方案,因为官方的docker方案只解决buildozer的问题,不解决其他的环境依赖问题。
构建问题处理以下整理了一些在使用过程中所遇到的问题,正是为了解决这些问题,所以我们后来放弃了在虚拟环境中继续测试的方法,改用本地环境直接来运行。这里有个区别需要注意,buildozer每次初始化会在特定帐号和环境的目录下产生一个.buildozer的目录,而普通帐号和root帐号的~/目录是不一样的,这点首先要明确。而如果使用虚拟环境,在虚拟环境下也可以产生一个独立的.buildozer目录。
dpkg的依赖安装我们使用了基于Arch的ManjaroLinux系统,大部分的软件通过pacman、yay和yaourt都是可以直接下载到的,当然,最好是配置好AUR的源,这里dpkg我们直接使用pacman来安装:
[dechin-rootkivy]]100%(1/1)正在检查密钥环里的密钥[]100%(1/1)正在加载软件包文件[]100%(1/1)正在检查可用存储空间[]100%/,*donot*!'vebeenwarned!::正在运行事务后钩子函数(1/1)ArmingConditionNeedsUpdate
中间如果没有报错即为安装成功。
基于docker的buildozer方案虽然并不是很推荐这个容器化方案,因为这个容器所能够解决的问题实在太少,但是这里我们还是展示一下buildozer官方容器的配置和使用方法。首先是下载官方镜像:
[dechin-rootkivy]dockerrun--volume"$(pwd)":/home/user/hostcwdkivy/
可以直接查看帮助:
[dechin-rootfirst_app]dockerrun-it--volume"$(pwd)":/home/user/hostcwd--privileged=Truekivy/buildozerinitTraceback(mostrecentcalllast):File"/home/user/.local/bin/buildozer",line8,(main())File"/home/user/.local/lib//site-packages/buildozer/scripts/",line13,inmainBuildozer().run_command([1:])File"/home/user/.local/lib//site-packages/buildozer/__init__.py",line1010,inrun_commandgetattr(self,cmd)(*args)File"/home/user/.local/lib//site-packages/buildozer/__init__.py",line1049,incmd_initcopyfile(join(dirname(__file__),''),'')File"/usr/lib//",line261,incopyfilewithopen(src,'rb')asfsrc,open(dst,'wb')asfdst:PermissionError:[Errno13]Permissiondenied:''
那就有可能是本地配置文件和目录权限的问题,因为目录是在普通帐号下产生的,一般是644的权限,那么就算是root权限的写入可能也会首先,干脆直接递归的改成777:
[dechin-rootkivy]dockerrun-it--volume"$(pwd)":/home/user/hostcwd--privileged=Truekivy/,readytocustomize!总用量24-rw-r--r--1dechindechin123054月410:59月410:42月410:43user
但是这个容器镜像跟常规的有所不同,整个的容器镜像就只能执行buildozer的指令,这尤其对国内用户非常的不友好,因为我们缺乏的就是buildozer那一堆依赖环境,在国内网络上会受到一定的限制。比如我们下述展示的运行结果,就卡在这个地方很久:
[dechin-rootfirst_app]CheckconfigurationtokensCreatedirectory/home/user/.buildozerCreatedirectory/home/user/hostcwd/.buildozerCreatedirectory/home/user/hostcwd/.buildozer/applibsCreatedirectory/home/user/hostcwd/.buildozer/android/platformCheckconfigurationtokensPreparingbuildRun'dpkg--version'SearchforGit(git)SearchforCython(cython)SearchforJavacompiler(javac)SearchforJavakeytool(keytool)InstallplatformCwd/home/user/hostcwd/.buildozer/android/platformCloninginto'python-for-android'
网络卡了很长一段时间后会弹出众多的报错:
Cloninginto'python-for-android'fatal:unabletoaccess'':GnuTLSrecverror(-54):='69325b48f53a'USER='user'WORK_DIR='/home/user/hostcwd'LANG='en_'LC_ALL='en_'Theerrormight/home/dechin/.buildozer/android/platformPerformingStreamedInstallSuccessRunonxxxCwd/home/dechin/.buildozer/android/platformStarting:Intent{act==/}(App):defbuild(self):color标签文本颜色font_size标签字体大小TogBu=ToggleButton(text="Red",color=(0,1,0,1),background_color=(0.5,0,0.5,1),font_size=200)returnTogBuif__name__=="__main__":ToggleButtonApp().run()执行结果的界面如下:
由于需要输入文本框,所以我们也得测试一下文本框的基本使用方法:
font_size输入文本框大小returntextif__name__=="__main__":TextInputApp().run()
运行结果如下:我们可以在界面上输入文本:
但是需要注意的是,我们在电脑端所看到的字体大小和手机端所看到的字体大小是不一致的,要根据实际情况来进行调整。
数学运算仓库math是python中非常常用的一个库,这里我们计划将其打包到一个安卓的app中,这样一来我们就可以在移动端调用python库来计算一些简单任务。那么我们的逻辑是这样的:先把所有的math函数导入,然后给定两个文本框,一个作为输入窗口一个作为输出窗口,再加上一个运行的按钮,那就齐活儿了。具体的成品代码如下:
font_size输入文本框大小_text=TextInput(font_size=150)button=Button(text="Run",size_hint=(1.0,0.5),pos_hint={"center_x":0.5,"center_y":0.5})(on_press=)_widget()_widget(_text)_widget(button)returnlayoutdefpress(self,instance):捕获异常,避免程序中断print(eval())如果是不合法信息,输出错误passif__name__=="__main__":TextInputApp().run()以下展示一些基本的运行结果:
该apk文件也已经传到百度网盘上面以供分享,感兴趣的朋友可以下载使用:
链接::4a3q
基于python也可以开发安卓APP,这需要使用到kivy库来进行开发,再通过buildozer来编译构建。这两个库的安装和使用方式都相对比较简单,我们推荐直接在本地的系统环境下直接部署使用,最大的困难其实在于部署的过程以及配置文件的修改,这也都是比较基础的操作了。最后我们演示了使用文本框和按钮事件,加上python的eval()函数和math数学仓库,实现了一个可以在移动端调用math库中的函数执行数学计算的简单APP,并提供了apk下载网盘地址。
版权声明本文首发链接为:
作者ID:DechinPhy
更多原著文章请参考:
免责声明:本文章如果文章侵权,请联系我们处理,本站仅提供信息存储空间服务如因作品内容、版权和其他问题请于本站联系