使用python中kivy库生成安卓APP
kivy的安装
官方推荐的方式是使用虚拟环境来进行安装和部署,关于虚拟环境的相关操作,在前面写过的一篇博客中有稍微详细一点的介绍,这里我们先给出操作步骤。假定我们已经在环境中用pip安装了virtualenv,那么我们先构建一个kivy的虚拟环境:
[dechin@dechin-manjaro kivy]$ virtualenv kivy_venv
created virtual environment CPython3.8.5.final.0-64 in 123ms
creator CPython3Posix(dest=/home/dechin/projects/2021-python/kivy/kivy_venv, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/dechin/.local/share/virtualenv)
added seed packages: pip==21.0.1, setuptools==54.1.2, wheel==0.36.2
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
构建完成后会在当前目录下生成一个文件夹:
[dechin@dechin-manjaro kivy]$ ll
总用量 4
drwxr-xr-x 4 dechin dechin 4096 4月 3 22:00 kivy_venv
我们可以用source ./kivy_env/bin/activate的方式对虚拟环境进行激活,激活后每次执行系统操作指令,会在指令的最前端显示一个虚拟环境的标识,比如这里我们在虚拟环境中用pip来安装kivy:
(kivy_venv)[dechin@dechin-manjaro kivy]$ python3 -m pip install kivy -i https://mirrors.cloud.tencent.com/pypi/simple
Looking in indexes: https://mirrors.cloud.tencent.com/pypi/simple
Collecting kivy
Downloading https://mirrors.cloud.tencent.com/pypi/packages/fd/4c/eb36890982bb11daaea68df62486ce36bde26cc9bec6a57e02c0e2aa8982/Kivy-2.0.0-cp38-cp38-manylinux2010_x86_64.whl (22.2 MB)
|████████████████████████████████| 22.2 MB 7.7 MB/s
Collecting pygments
Downloading https://mirrors.cloud.tencent.com/pypi/packages/3a/80/a52c0a7c5939737c6dca75a831e89658ecb6f590fb7752ac777d221937b9/Pygments-2.8.1-py3-none-any.whl (983 kB)
|████████████████████████████████| 983 kB 688 kB/s
Collecting Kivy-Garden>=0.1.4
Downloading https://mirrors.cloud.tencent.com/pypi/packages/7d/68/decaee596ff8168a39432eb3949fc7c0be952ebb9467806823bffc165d48/kivy-garden-0.1.4.tar.gz (6.8 kB)
Collecting docutils
Downloading https://mirrors.cloud.tencent.com/pypi/packages/9a/65/76aea825b59727b556cca74e28d68e4d73244d2e1e8a8945c29d6d3d5e11/docutils-0.17-py2.py3-none-any.whl (575 kB)
|████████████████████████████████| 575 kB 912 kB/s
Collecting requests
Downloading https://mirrors.cloud.tencent.com/pypi/packages/29/c1/24814557f1d22c56d50280771a17307e6bf87b70727d975fd6b2ce6b014a/requests-2.25.1-py2.py3-none-any.whl (61 kB)
|████████████████████████████████| 61 kB 1.0 MB/s
Collecting certifi>=2017.4.17
Downloading https://mirrors.cloud.tencent.com/pypi/packages/5e/a0/5f06e1e1d463903cf0c0eebeb751791119ed7a4b3737fdc9a77f1cdfb51f/certifi-2020.12.5-py2.py3-none-any.whl (147 kB)
|████████████████████████████████| 147 kB 726 kB/s
Collecting idna<3,>=2.5
Downloading https://mirrors.cloud.tencent.com/pypi/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl (58 kB)
|████████████████████████████████| 58 kB 644 kB/s
Collecting urllib3<1.27,>=1.21.1
Downloading https://mirrors.cloud.tencent.com/pypi/packages/09/c6/d3e3abe5b4f4f16cf0dfc9240ab7ce10c2baa0e268989a4e3ec19e90c84e/urllib3-1.26.4-py2.py3-none-any.whl (153 kB)
|████████████████████████████████| 153 kB 564 kB/s
Collecting chardet<5,>=3.0.2
Downloading https://mirrors.cloud.tencent.com/pypi/packages/19/c7/fa589626997dd07bd87d9269342ccb74b1720384a4d739a1872bd84fbe68/chardet-4.0.0-py2.py3-none-any.whl (178 kB)
|████████████████████████████████| 178 kB 827 kB/s
Building wheels for collected packages: Kivy-Garden
Building wheel for Kivy-Garden (setup.py) ... done
Created wheel for Kivy-Garden: filename=Kivy_Garden-0.1.4-py3-none-any.whl size=4532 sha256=70dd6bf0a005868e9aca0710f7b717432bda7925c0fac236b99d2527ec112b78
Stored in directory: /home/dechin/.cache/pip/wheels/c9/d0/d4/2cb72931b74be8ce5fbee5ed87d66366f356a3161ea772d015
Successfully built Kivy-Garden
Installing collected packages: urllib3, idna, chardet, certifi, requests, pygments, Kivy-Garden, docutils, kivy
Successfully installed Kivy-Garden-0.1.4 certifi-2020.12.5 chardet-4.0.0 docutils-0.17 idna-2.10 kivy-2.0.0 pygments-2.8.1 requests-2.25.1 urllib3-1.26.4
为了加快安装,我们使用了腾讯的pip源。安装完成后,可以在已安装列表中看到刚才安装的kivy及其依赖组件:
(kivy_venv)[dechin@dechin-manjaro kivy]$ python3 -m pip list
Package Version
----------- ---------
certifi 2020.12.5
chardet 4.0.0
docutils 0.17
idna 2.10
Kivy 2.0.0
Kivy-Garden 0.1.4
pip 21.0.1
Pygments 2.8.1
requests 2.25.1
setuptools 54.1.2
urllib3 1.26.4
wheel 0.36.2
kivy的hello world
配置好kivy的环境后,我们可以直接在电脑端测试python所编写的app实例,比如kivy的hello world:
# kivy_hello_world.py
import kivy
kivy.require('2.0.0') # 注意匹配版本号
from kivy.app import App
from kivy.uix.label import Label
class MyApp(App):
def build(self):
return Label(text='Hello world')
if __name__ == '__main__':
MyApp().run()
可以直接用python3 kivy_hello_world.py
的指令来执行,执行结果如下图所示:
执行期间我们可以在屏幕上看到一系列的日志输出,在有报错问题的时候,查询执行日志是必须使用的定位手段:
[INFO ] [Logger ] Record log in /home/dechin/.kivy/logs/kivy_21-04-03_1.txt
[INFO ] [Kivy ] v2.0.0
[INFO ] [Kivy ] Installed at "/home/dechin/projects/2021-python/kivy/kivy_venv/lib/python3.8/site-packages/kivy/__init__.py"
[INFO ] [Python ] v3.8.5 (default, Sep 4 2020, 07:30:14)
[GCC 7.3.0]
[INFO ] [Python ] Interpreter at "/home/dechin/projects/2021-python/kivy/kivy_venv/bin/python3"
[INFO ] [Factory ] 186 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2 (img_pil, img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2
[INFO ] [Window ] Provider: sdl2
[INFO ] [GL ] Using the "OpenGL" graphics system
[INFO ] [GL ] Backend used <sdl2>
[INFO ] [GL ] OpenGL version <b'4.6 (Compatibility Profile) Mesa 20.3.1'>
[INFO ] [GL ] OpenGL vendor <b'Intel'>
[INFO ] [GL ] OpenGL renderer <b'Mesa Intel(R) UHD Graphics 620 (WHL GT2)'>
[INFO ] [GL ] OpenGL parsed version: 4, 6
[INFO ] [GL ] Shading version <b'4.60'>
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <32>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [ProbeSysfs ] device match: /dev/input/event16
[INFO ] [MTD ] Read event from </dev/input/event16>
[INFO ] [Base ] Start application main loop
[INFO ] [GL ] NPOT texture support is available
[WARNING] [MTD ] Unable to open device "/dev/input/event16". Please ensure you have the appropriate permissions.
[INFO ] [Base ] Leaving application in progress...
到这里,我们的第一步工作就基本完成了,但是需要注意的是,这里我们的程序还是运行在电脑端的,我们需要将其打包成apk文件之后,才能在手机端运行。
选择使用虚拟环境的原因
这里我们单独一个小章节,说明一下为什么官方推荐的使用方法很多都是使用虚拟环境,这个其实跟后面要介绍的apk打包有较大关系。我们在打包apk的过程中,如果有相关的python依赖包,都需要在配置文件中提前标识。这一点非常重要,最好是能够指定具体的版本号进行安装,否则会出现打包失败的问题,如果到了打包的阶段再去定位和解决此类问题,会非常的麻烦。
apk构建环境配置
我们在本地采用了buildozer的方案来进行apk的构建,如果在本地其他环境依赖如jdk等都已经部署完毕,在虚拟环境里面直接安装buildozer是没有问题的。但是由于本地环境中依赖都比较缺乏,因此为了避免环境切换混乱,这里我们使用虚拟环境来展示安装和使用的基本方法,但是实际应用场景下,我们还是直接使用了本地的python3环境,而不是虚拟环境。
安装buildozer
跟其他python库一样的,我们可以通过pip来对buildozer进行安装和管理:
(kivy_venv)[dechin@dechin-manjaro kivy]$ python3 -m pip install buildozer -i https://mirrors.cloud.tencent.com/pypi/simple
Looking in indexes: https://mirrors.cloud.tencent.com/pypi/simple
Collecting buildozer
Downloading https://mirrors.cloud.tencent.com/pypi/packages/ac/62/a53738c604ebc86d3b62f654c3169e8c0b4178a066d7398cf53377a5cb3b/buildozer-1.2.0-py3-none-any.whl (77 kB)
|████████████████████████████████| 77 kB 783 kB/s
Collecting sh
Downloading https://mirrors.cloud.tencent.com/pypi/packages/50/38/f7dcc62943d0870f02df9e2fa527b7f0cd86b233a80d6e503a08f3ef5ddc/sh-1.14.1-py2.py3-none-any.whl (40 kB)
|████████████████████████████████| 40 kB 1.7 MB/s
Collecting pexpect
Downloading https://mirrors.cloud.tencent.com/pypi/packages/39/7b/88dbb785881c28a102619d46423cb853b46dbccc70d3ac362d99773a78ce/pexpect-4.8.0-py2.py3-none-any.whl (59 kB)
|████████████████████████████████| 59 kB 1.0 MB/s
Collecting virtualenv
Downloading https://mirrors.cloud.tencent.com/pypi/packages/91/fb/ca6c071f4231e06a9f0c3bd81c15c233bbacd4a7d9dbb7438d95fece8a1e/virtualenv-20.4.3-py2.py3-none-any.whl (7.2 MB)
|████████████████████████████████| 7.2 MB 2.2 MB/s
Collecting ptyprocess>=0.5
Downloading https://mirrors.cloud.tencent.com/pypi/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl (13 kB)
Collecting distlib<1,>=0.3.1
Downloading https://mirrors.cloud.tencent.com/pypi/packages/f5/0a/490fa011d699bb5a5f3a0cf57de82237f52a6db9d40f33c53b2736c9a1f9/distlib-0.3.1-py2.py3-none-any.whl (335 kB)
|████████████████████████████████| 335 kB 721 kB/s
Collecting six<2,>=1.9.0
Downloading https://mirrors.cloud.tencent.com/pypi/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting appdirs<2,>=1.4.3
Downloading https://mirrors.cloud.tencent.com/pypi/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB)
Collecting filelock<4,>=3.0.0
Downloading https://mirrors.cloud.tencent.com/pypi/packages/93/83/71a2ee6158bb9f39a90c0dea1637f81d5eef866e188e1971a1b1ab01a35a/filelock-3.0.12-py3-none-any.whl (7.6 kB)
Installing collected packages: six, ptyprocess, filelock, distlib, appdirs, virtualenv, sh, pexpect, buildozer
Successfully installed appdirs-1.4.4 buildozer-1.2.0 distlib-0.3.1 filelock-3.0.12 pexpect-4.8.0 ptyprocess-0.7.0 sh-1.14.1 six-1.15.0 virtualenv-20.4.3
安装完成后,应该要在本地可以看到buildozer的安装位置:
(kivy_venv)[dechin@dechin-manjaro kivy]$ which buildozer
/home/dechin/projects/2021-python/kivy/kivy_venv/bin/buildozer
buildozer的基本使用
从框架上来说,buildozer的使用方法其实只有两个步骤:先用init生成配置文件,然后使用buildozer debug就可以构造一个apk文件了,如果顺利的话:)
(kivy_venv) [dechin@dechin-manjaro kivy]$ buildozer init
File buildozer.spec created, ready to customize!
按照流程第一步初始化完成后,当前的目录下会生成一个buildozer.spec的配置文件,与其他软件所不一样的是,这个配置文件又臭又长,修改起来非常的不便,对新手极其不友好。但是,运气好的情况下也不需要去修改这个配置文件就可以成功构建apk。
(kivy_venv) [dechin@dechin-manjaro kivy]$ ll
总用量 24
-rw-r--r-- 1 dechin dechin 10489 4月 3 22:17 buildozer.spec
-rw-r--r-- 1 dechin dechin 243 4月 3 22:06 kivy_hello_world.py
drwxr-xr-x 4 dechin dechin 4096 4月 3 22:00 kivy_venv
当你执行下面的指令,正常情况下麻烦才刚刚开始:
(kivy_venv) [dechin@dechin-manjaro kivy]$ buildozer android debug deploy run
# Check configuration tokens
# Ensure build layout
# Create directory /home/dechin/.buildozer
# Create directory /home/dechin/.buildozer/cache
# Create directory /home/dechin/projects/2021-python/kivy/.buildozer
# Create directory /home/dechin/projects/2021-python/kivy/bin
# Create directory /home/dechin/projects/2021-python/kivy/.buildozer/applibs
# Create directory /home/dechin/.buildozer/android/platform/android/platform
# Create directory /home/dechin/projects/2021-python/kivy/.buildozer/android/platform
# Create directory /home/dechin/projects/2021-python/kivy/.buildozer/android/app
# Check configuration tokens
# Read available permissions from api-versions.xml
# Preparing build
# Check requirements for android
# Run 'dpkg --version'
# Cwd None
/bin/sh:行1: dpkg:未找到命令
# Search for Git (git)
# -> found at /usr/bin/git
# Search for Cython (cython)
# -> found at /home/dechin/anaconda3/bin/cython
# Search for Java compiler (javac)
# Java compiler (javac) not found, please install it.
没有dpkg,没有jdk,在参考链接5里面还有人专门整理了各种可能猜到的坑,对这些环境有依赖,为何不能在文档中提前说明呢?这里还有一点需要注意的是,虽然buildozer官方提供了docker的解决方案,但是我们极其不推荐使用官方提供的docker解决方案,因为官方的docker方案只解决buildozer的问题,不解决其他的环境依赖问题。
构建问题处理
以下整理了一些在使用过程中所遇到的问题,正是为了解决这些问题,所以我们后来放弃了在虚拟环境中继续测试的方法,改用本地环境直接来运行。这里有个区别需要注意,buildozer每次初始化会在特定帐号和环境的目录下产生一个.buildozer的目录,而普通帐号和root帐号的~/目录是不一样的,这点首先要明确。而如果使用虚拟环境,在虚拟环境下也可以产生一个独立的.buildozer目录。
dpkg的依赖安装
我们使用了基于Arch的Manjaro Linux系统,大部分的软件通过pacman、yay和yaourt都是可以直接下载到的,当然,最好是配置好AUR的源,这里dpkg我们直接使用pacman来安装:
[dechin-root kivy]# pacman -S dpkg
正在解析依赖关系...
正在查找软件包冲突...
软件包 (1) dpkg-1.20.5-2
下载大小: 1.75 MiB
全部安装大小: 8.26 MiB
:: 进行安装吗? [Y/n] Y
:: 正在获取软件包......
dpkg-1.20.5-2-x86_64 1795.8 KiB 524 KiB/s 00:03 [#############################] 100%
(1/1) 正在检查密钥环里的密钥 [#############################] 100%
(1/1) 正在检查软件包完整性 [#############################] 100%
(1/1) 正在加载软件包文件 [#############################] 100%
(1/1) 正在检查文件冲突 [#############################] 100%
(1/1) 正在检查可用存储空间 [#############################] 100%
:: 正在处理软件包的变化...
(1/1) 正在安装 dpkg [#############################] 100%
dpkg installs Debian package manager.
This is useful for those who want to create/modify DEB files.
However, *do not* use dpkg to install Debian packages in your ArchLinux machine.
This will break your system!
You will need to go back to Arch wiki and read the installation guide again.
You've been warned!
:: 正在运行事务后钩子函数...
(1/1) Arming ConditionNeedsUpdate...
中间如果没有报错即为安装成功。
基于docker的buildozer方案
虽然并不是很推荐这个容器化方案,因为这个容器所能够解决的问题实在太少,但是这里我们还是展示一下buildozer官方容器的配置和使用方法。首先是下载官方镜像:
[dechin-root kivy]# docker pull kivy/buildozer
Using default tag: latest
latest: Pulling from kivy/buildozer
5d3b2c2d21bb: Pull complete
3fc2062ea667: Pull complete
75adf526d75b: Pull complete
1e25f7347ef2: Pull complete
5f20dec9b37e: Pull complete
50f409884337: Pull complete
eee420e57cec: Pull complete
cf2da2cede0f: Pull complete
6581da051d43: Pull complete
e9f936019286: Pull complete
517947681358: Pull complete
Digest: sha256:b2923081b45829555cd27356fbc0ab364474c64d9879fa730eccd4ce63e22cc4
Status: Downloaded newer image for kivy/buildozer:latest
docker.io/kivy/buildozer:latest
下载完成后,绑定当前目录运行容器镜像:
[dechin-root first_app]# docker run --volume "$(pwd)":/home/user/hostcwd kivy/buildozer
Buildozer 1.2.0.dev0
可以直接查看帮助:
[dechin-root first_app]# docker run -it --volume "$(pwd)":/home/user/hostcwd kivy/buildozer --help
Usage:
buildozer [--profile <name>] [--verbose] [target] <command>...
buildozer --version
Available targets:
ios iOS target, based on kivy-ios project
android Android target, based on python-for-android project
Global commands (without target):
appclean Clean the .buildozer folder in the app directory.
distclean Clean the whole Buildozer environment.
help Show the Buildozer help.
init Create a initial buildozer.spec in the current directory
serve Serve the bin directory via SimpleHTTPServer
setdefault Set the default command to run when no arguments are given
version Show the Buildozer version
Target commands:
clean Clean the target environment
update Update the target dependencies
debug Build the application in debug mode
release Build the application in release mode
deploy Deploy the application on the device
run Run the application on the device
serve Serve the bin directory via SimpleHTTPServer
Target "ios" commands:
list_identities List the available identities to use for signing.
xcode Open the xcode project.
Target "android" commands:
adb Run adb from the Android SDK. Args must come after --, or
use --alias to make an alias
clean Clean the build and distribution
logcat Show the log from the device
p4a Run p4a commands. Args must come after --, or use --alias
to make an alias
第一次初始化,出现了权限不足的问题,一开始以为是容器内部读写权限配置的问题,因此这里先给容器加上了privileged权限,但是执行后发现这个问题依然存在:
[dechin-root first_app]# docker run -it --volume "$(pwd)":/home/user/hostcwd --privileged=True kivy/buildozer init
Traceback (most recent call last):
File "/home/user/.local/bin/buildozer", line 8, in <module>
sys.exit(main())
File "/home/user/.local/lib/python3.8/site-packages/buildozer/scripts/client.py", line 13, in main
Buildozer().run_command(sys.argv[1:])
File "/home/user/.local/lib/python3.8/site-packages/buildozer/__init__.py", line 1010, in run_command
getattr(self, cmd)(*args)
File "/home/user/.local/lib/python3.8/site-packages/buildozer/__init__.py", line 1049, in cmd_init
copyfile(join(dirname(__file__), 'default.spec'), 'buildozer.spec')
File "/usr/lib/python3.8/shutil.py", line 261, in copyfile
with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
PermissionError: [Errno 13] Permission denied: 'buildozer.spec'
那就有可能是本地配置文件和目录权限的问题,因为目录是在普通帐号下产生的,一般是644的权限,那么就算是root权限的写入可能也会首先,干脆直接递归的改成777:
[dechin-root kivy]# chmod -R 777 first_app/
再次运行,发现在本地一样也可以生成配置文件:
[dechin-root first_app]# docker run -it --volume "$(pwd)":/home/user/hostcwd --privileged=True kivy/buildozer init && ll
File buildozer.spec created, ready to customize!
总用量 24
-rw-r--r-- 1 dechin dechin 12305 4月 4 10:59 buildozer.spec
-rwxrwxrwx 1 root root 243 4月 4 10:42 main.py
drwxrwxrwx 3 root root 4096 4月 4 10:43 user
但是这个容器镜像跟常规的有所不同,整个的容器镜像就只能执行buildozer的指令,这尤其对国内用户非常的不友好,因为我们缺乏的就是buildozer那一堆依赖环境,在国内网络上会受到一定的限制。比如我们下述展示的运行结果,就卡在这个地方很久:
[dechin-root first_app]# docker run -it --volume "$(pwd)":/home/user/hostcwd --privileged=True kivy/buildozer android debug deploy run
# Check configuration tokens
# Ensure build layout
# Create directory /home/user/.buildozer
# Create directory /home/user/.buildozer/cache
# Create directory /home/user/hostcwd/.buildozer
# Create directory /home/user/hostcwd/bin
# Create directory /home/user/hostcwd/.buildozer/applibs
# Create directory /home/user/.buildozer/android/platform/android/platform
# Create directory /home/user/hostcwd/.buildozer/android/platform
# Create directory /home/user/hostcwd/.buildozer/android/app
# Check configuration tokens
# Read available permissions from api-versions.xml
# Preparing build
# Check requirements for android
# Run 'dpkg --version'
# Cwd None
Debian 'dpkg' package management program version 1.19.7 (amd64).
This is free software; see the GNU General Public License version 2 or
later for copying conditions. There is NO warranty.
# Search for Git (git)
# -> found at /usr/bin/git
# Search for Cython (cython)
# -> found at /home/user/.local/bin/cython
# Search for Java compiler (javac)
# -> found at /usr/lib/jvm/java-13-openjdk-amd64/bin/javac
# Search for Java keytool (keytool)
# -> found at /usr/lib/jvm/java-13-openjdk-amd64/bin/keytool
# Install platform
# Run 'git clone -b master --single-branch https://github.com/kivy/python-for-android.git python-for-android'
# Cwd /home/user/hostcwd/.buildozer/android/platform
Cloning into 'python-for-android'...
网络卡了很长一段时间后会弹出众多的报错:
Cloning into 'python-for-android'...
fatal: unable to access 'https://github.com/kivy/python-for-android.git/': GnuTLS recv error (-54): Error in the pull function.
# Command failed: git clone -b master --single-branch https://github.com/kivy/python-for-android.git python-for-android
# ENVIRONMENT:
# PATH = '/home/user/.buildozer/android/platform/apache-ant-1.9.4/bin:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
# HOSTNAME = '69325b48f53a'
# TERM = 'xterm'
# USER = 'user'
# HOME_DIR = '/home/user'
# WORK_DIR = '/home/user/hostcwd'
# SRC_DIR = '/home/user/src'
# LANG = 'en_US.UTF-8'
# LANGUAGE = 'en_US.UTF-8'
# LC_ALL = 'en_US.UTF-8'
# HOME = '/home/user'
#
# Buildozer failed to execute the last command
# The error might be hidden in the log above this error
# Please read the full log, and search for it before
# raising an issue with buildozer itself.
# In case of a bug report, please add a full log with log_level = 2
实际上这就是网络的问题,如果你能上谷歌,那么你就同时解决了这个问题。如果网络不行的话,即使在官方商店里面可以看到也是下载安装不了的:
adb日志定位apk问题
假定你已经解决了上述提到了访问谷歌网站的问题,那么环境依赖的问题基本上就已经解决了,只需要注意jdk跟gradle的版本配套关系即可,这里我们本地使用的是jdk-8,同样的也可以使用yaourt来进行安装。最后就还有可能出现,部署到安卓设备上面之后,app闪退的问题。首先我们如果执行buildozer androiid debug deploy run,并且同时保障安卓手机USB接入以及USB调试开关的打开,顺利情况下会出现以下信息:
List of devices attached
xxx device
# Deploy on xxx
# Run '/home/dechin/.buildozer/android/platform/android-sdk/platform-tools/adb install -r "/home/dechin/projects/2021-python/kivy/first_app/bin/myapp-0.1-armeabi-v7a-debug.apk"'
# Cwd /home/dechin/.buildozer/android/platform
Performing Streamed Install
Success
# Application pushed.
# Run on xxx
# Run '/home/dechin/.buildozer/android/platform/android-sdk/platform-tools/adb shell am start -n org.test.myapp/org.kivy.android.PythonActivity -a org.kivy.android.PythonActivity'
# Cwd /home/dechin/.buildozer/android/platform
Starting: Intent { act=org.kivy.android.PythonActivity cmp=org.test.myapp/org.kivy.android.PythonActivity }
# Application started.
但这并不是终点,我们发现在手机上用apk安装的app会出现闪退,这一般都是由于程序报错而导致的,我们可以在连接USB调试的状态下,进入adb shell查看日志:
[dechin@dechin-manjaro first_app]$ adb shell
HWPCT:/ $ run-as org.test.myapp
HWPCT:/data/data/org.test.myapp
$ cd files/app/.kivy/logs/
HWPCT:/data/data/org.test.myapp/files/app/.kivy/logs
$ ls
kivy_21-04-06_0.txt
$ cat kivy_21-04-06_0.txt <
[INFO ] Logger: Record log in /data/user/0/org.test.myapp/files/app/.kivy/logs/kivy_21-04-06_0.txt
[WARNING] [Config ] Upgrading configuration in progress.
[WARNING] [Config ] Older configuration version detected (0 instead of 21)
[INFO ] Kivy: v1.11.1
[INFO ] Kivy: Installed at "/data/user/0/org.test.myapp/files/app/_python_bundle/site-packages/kivy/__init__.pyc"
[INFO ] Python: v3.8.1 (default, Apr 6 2021, 10:41:43)
[Clang 8.0.2 (https://android.googlesource.com/toolchain/clang 40173bab62ec7462
[INFO ] Python: Interpreter at ""
[WARNING] stderr: Traceback (most recent call last):
[WARNING] stderr: File "/home/dechin/projects/2021-python/kivy/first_app/.buildozer/android/app/main.py", line 4, in <module>
[WARNING] stderr: File "/home/dechin/projects/2021-python/kivy/first_app/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/__init__.py", line 138, in require
[WARNING] stderr: Exception: The version of Kivy installed on this system is too old. (You have 1.11.1, but the application requires 2.0.0)
HWPCT:/data/data/org.test.myapp/files/app/.kivy/log
从日志中我们看到,这是因为对应的kivy程序版本过低导致的,这需要我们修改buildozer.spec配置文件。我们找到requirements这里,发现这里的两个仓库都没有指定版本号,这里我们采取的方案是加上版本号的要求,然后清除.buildozer目录,重新进行环境安装。
requirements = python3,kivy
修改后如下:
requirements = python3,kivy==2.0.0
然后在重新执行buildozer debug deploy run,得到手机界面上的效果如下(如果只运行debug或者release,那就不需要连接手机USB调试,这里的操作相当于直接把apk传输到手机上进行安装和运行):
总结
基于python也可以开发安卓APP,这需要使用到kivy库来进行开发,再通过buildozer来编译构建。这两个库的安装和使用方式都相对比较简单,我们推荐直接在本地的系统环境下直接部署使用,最大的困难其实在于部署的过程以及配置文件的修改,这也都是比较基础的操作了。最后我们演示了使用文本框和按钮事件,加上python的eval()函数和math数学仓库,实现了一个可以在移动端调用math库中的函数执行数学计算的简单APP,并提供了apk下载网盘地址。