《Buildozer打包实战指南》第四节 正式打包一个apk文件

news2024/11/25 18:41:25

目录

4.1 了解buildozer.spec配置文件中的常用参数

4.2 修改配置文件打包apk


在上一节内容中,我们配置好了打包环境,还顺带成功打包出了一个apk文件(读者可以把这个apk安装到手机上运行)。不过在打包这个apk前,我们没有修改buildozer.spec配置文件中的内容。在本节,笔者会带大家了解下配置文件中的一些常用参数,并正式打包一个apk文件。

4.1 了解buildozer.spec配置文件中的常用参数

title:应用名称。名称不要太长,否则会在界面上显示不完全。而且最好不要使用奇奇怪怪的字符,不一定能够成功显示。

package.name:apk的包名称。不要出现特殊字符,用全英文。

package.domain:该参数应包含开发者信息,而且会用作apk包的标识符。比如一家名为ABC的公司开发了一个记事本应用,那这个参数可以填写成com.abc.notebook。有很多包命名的规范,大家可以网上用关键词“安卓包命名规范”搜索下。

source.dir:包含被打包的入口程序(即main.py)所在的文件夹路径。

source.include_exts:打包时要包含进去的文件类型,不在这个参数中表明的文件类型是不会被打包进去的。如果这个参数不填,值是空白的话,就表示会打包所有文件。

source.include_patterns:使用模式匹配表示要打包进去的文件。

source.exclude_exts:打包时要排除的文件类型。

source.exclude_dirs:打包时要排除的文件夹名称,即该文件夹中的文件不会被打包进去。

source.exclude_patterns:使用模式匹配表示不会打包进去的文件。

version:包版本。和程序第一行__version__ = "1.0.0"代码中填写的版本一样即可。当然,如果程序中没有写版本信息的话,填写该参数也是一样的。

version.regex和version.filename:前者匹配类似这样的代码__version__ = "1.0.0"行;后者指定包含版本代码的py文件。如果version参数没有填,那通过这两个参数,Buildozer会自动从程序中获取版本信息。

requirements:应用包含的库或模块。该参数非常重要,必须填写正确。读者在程序中导入的库或模块都在填写在这个参数中。比方说,我们使用了kivy和requests这两个库,那么该参数就可以写成下面这样。

requirements = kivy,requests

requirements.source.kivy:指定要打包进去的kivy库文件夹路径,如果注释掉该参数的话,Buildozer会自动去Python的安装路径下去寻找这个库。如果要指定requests库的文件夹路径,那可以再配置文件中再加上一行requirements.source.requests = requests库文件夹的路径。

presplash.filename:应用启动画面图片路径。

 icon.filename:应用图标的路径。

orientation:应用横屏还是竖屏显示。landscape表示横屏,portrait表示竖屏,sensorLandscape也是横屏,但会根据手机方向自动适应调整,all表示都可以。

fullscreen:是否全屏显示,默认是全屏。0的话表示非全屏,我们还可以看到手机的状态栏。要全屏的话可以填写1。

4.2 修改配置文件打包apk

在上一节打包后,demo文件夹下出现了两个新的文件夹:bin和.buildozer。

打包生成的apk会放在bin文件夹中,而.buildozer文件夹则包含一些依赖文件。如果我们要打包一个类似的程序,可以不用.buildozer文件夹删除了再重新打包(bin文件夹可以删除),否则可能某些依赖文件就需要重新下载,很浪费时间,更不用说可能还会因为网络原因下载失败。如果针对新程序的某些依赖文件不存在,Buildozer会再去另外下载。

如果是要打包完全不同的程序(指用的库或模块完全不同),则建议全部删除后再重新下载依赖打包(防止出现一些难搞的报错),不过某些依赖文件像Android SDK、NDK等是存放在主目录文件夹下的,打包时Buildozer会从这里面直接复制,不会再重新下载。

现在我们开始打包一个新的程序,程序代码来自Kivy官方文档。虽然程序与上一节内容中的类似,只使用了kivy,但笔者还是决定带大家从头开始一步步演示,这样大家也可以更熟悉一些。

第一步:删除之前打包生成的bin以及buildozer.spec,把.buildozer移到其他路径下,然后在终端中输入touch pong.kv生成一个kv格式的文件。

注:之所以不删除之前打包生成的.buildozer文件夹,而是移到其他路径下,是担心重新打包时会因为网络原因下载不了某些文件。如果出现这样的情况,那可以直接从之前的.buildozer文件夹中复制相关文件,节省时间。

第二步:分别在main.py和pong.kv中输入以下代码。

注:笔者删除了官方文档中pong.kv的第一行代码 #:kivy 1.0.9

main.py

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import (
    NumericProperty, ReferenceListProperty, ObjectProperty
)
from kivy.vector import Vector
from kivy.clock import Clock


class PongPaddle(Widget):
    score = NumericProperty(0)

    def bounce_ball(self, ball):
        if self.collide_widget(ball):
            vx, vy = ball.velocity
            offset = (ball.center_y - self.center_y) / (self.height / 2)
            bounced = Vector(-1 * vx, vy)
            vel = bounced * 1.1
            ball.velocity = vel.x, vel.y + offset


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
    ball = ObjectProperty(None)
    player1 = ObjectProperty(None)
    player2 = ObjectProperty(None)

    def serve_ball(self, vel=(4, 0)):
        self.ball.center = self.center
        self.ball.velocity = vel

    def update(self, dt):
        self.ball.move()

        # bounce of paddles
        self.player1.bounce_ball(self.ball)
        self.player2.bounce_ball(self.ball)

        # bounce ball off bottom or top
        if (self.ball.y < self.y) or (self.ball.top > self.top):
            self.ball.velocity_y *= -1

        # went of to a side to score point?
        if self.ball.x < self.x:
            self.player2.score += 1
            self.serve_ball(vel=(4, 0))
        if self.ball.right > self.width:
            self.player1.score += 1
            self.serve_ball(vel=(-4, 0))

    def on_touch_move(self, touch):
        if touch.x < self.width / 3:
            self.player1.center_y = touch.y
        if touch.x > self.width - self.width / 3:
            self.player2.center_y = touch.y


class PongApp(App):
    def build(self):
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game


if __name__ == '__main__':
    PongApp().run()

pong.kv

<PongBall>:
    size: 50, 50 
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size          

<PongPaddle>:
    size: 25, 200
    canvas:
        Rectangle:
            pos: self.pos
            size: self.size

<PongGame>:
    ball: pong_ball
    player1: player_left
    player2: player_right
    
    canvas:
        Rectangle:
            pos: self.center_x - 5, 0
            size: 10, self.height
    
    Label:
        font_size: 70  
        center_x: root.width / 4
        top: root.top - 50
        text: str(root.player1.score)
        
    Label:
        font_size: 70  
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: str(root.player2.score)
    
    PongBall:
        id: pong_ball
        center: self.parent.center
        
    PongPaddle:
        id: player_left
        x: root.x
        center_y: root.center_y
        
    PongPaddle:
        id: player_right
        x: root.width - self.width
        center_y: root.center_y

第三步:在终端中输入python3 main.py命令运行main.py,确保程序运行正常。读者可以用鼠标拖动两边的白板试玩下。

第四步:在终端中输入buildozer init命令生成配置文件。

第五步:从iconfont网站上下载一个大小为128px的icon图标文件,放到共享文件夹中后复制到demo文件夹下。

第六步:修改配置文件中的一些参数。

title = Pong Game

package.name = ponggame

package.domain = org.louis.ponggame

version = 1.0.0

icon.filename = game.png

orientation = landscape

第七步:将配置文件保存后,在终端中输入buildozer -v android debug命令开始打包。

最终打包成功,我们可以在bin文件夹中看到生成的apk文件。

在模拟器中也运行成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/169163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity学习笔记--如何在Unity运行cmd?并且在Unity中利用cmd操作svn(例如生成svn--diff文件)

目录前言需求拆分解决方案实操前言 最近工作有一个需求&#xff0c;简单来说是在 Unity 里面动态获取 SVN diff 的数据&#xff0c;并且针对这些 diff 文件做对应操作 需求拆分 我们首先拆分下需求 Unity里面获取 SVN 的 diff 文件针对生成的 diff 文件做解析&#xff0c;找…

Qt 视频播放

一、简介Qt对音视频的播放和控制&#xff0c;相机拍照&#xff0c;收音机等多媒体应用提供了强大的支持。Qt5使用了全新的Qt Multimedia模块来实现多媒体应用&#xff0c;而原来Qt4中用于实现多媒体功能的Phonon模块已经被移除。新的Qt Multimedia模块提供了丰富的接口&#xf…

【从零开始学习深度学习】50.Pytorch_NLP项目实战:卷积神经网络textCNN在文本情感分类的运用

在之前介绍的“卷积神经网络”中我们探究了如何使用二维卷积神经网络来处理二维图像数据。在语言模型和文本分类任务中&#xff0c;我们将文本数据看作是只有一个维度的时间序列&#xff0c;并很自然地使用循环神经网络来表征这样的数据。其实&#xff0c;我们也可以将文本当作…

安装 MySQL

1.下载安装文件 访问MySQL官网下载安装文件。 如下图所示&#xff0c;点击页面中的“DOWNLOAD”按钮。 点击下载之后自动进行下载。下载到本地的文件名称为&#xff1a;mysql-8.0.31-winx64.zip 2.解压安装文件 将压缩文件解压到你安装的目录&#xff0c;比如&#xff1a;F:…

数据结构与算法笔记

0 核心框架汇总 框架思维 数据结构的存储方式只有两种&#xff1a;数组&#xff08;顺序存储&#xff09;和链表&#xff08;链式存储&#xff09; 算法 数学中的算法重在推导&#xff0c;计算机中的算法重在穷举 计算机算法的本质特点&#xff1a; 穷举 穷举有两个关键难点…

Linux环境 java应用问题排查

0&#xff09;查看CPU占用高的进程PID top -d 1 或 top -H 注&#xff1a; top -d 1 中的 1 是数字&#xff1a;1&#xff0c;不是字母 &#xff1a;l 。 1&#xff09;查看内存使用情况&#xff08;memory-info.log为具体文件路径&#xff09; jmap -heap PID > memory-i…

某程序员跳槽涨薪50%!网友:不合理~

在IT届&#xff0c;有个传闻&#xff0c;跳槽就是程序猿涨工资最好的方式。大家认为程序员跳槽要求涨薪50%合理吗&#xff1f;有人说&#xff1a;凭本事涨的为啥不合理&#xff01;01程序员跳槽要求涨薪50%过分吗&#xff1f;在知乎上看到这样一个帖子&#xff0c;有人提问“程…

CANoe 15版本中CAPL代码自动补全功能的小Bug

最近在使用CANoe 15版本的软件编写CAPL脚本时,遇到了一些小的困扰,记录下来分享给大家! 当我在capl函数中要传入两个参数时,除了逗号隔开两个参数外,还希望有一个空格能进一步拉开两个参数的距离,增加代码的可读性 但是,传入第一个参数后,输入逗号,此时capl的自动补…

IP 网络主动监测系统 Renix Active

一、IT网络运维面临的挑战​ 1.网络性能可视化​ • 与公有云和SaaS平台连接的可靠性​ • 广域网线路性能​ • 互联网专线性能​ 2.诊断工具​ • 现场无IT工程师覆盖​ • 诊断的人力费用​ • 网络与应用系统的纠结​ 3.用户体验​ • Web应用的访问质量​ • 语…

C++设计模式(2)——工厂方法模式

亦称&#xff1a; 虚拟构造函数、Virtual Constructor、Factory Method 意图 工厂方法模式是一种创建型设计模式&#xff0c; 其在父类中提供一个创建对象的方法&#xff0c; 允许子类决定实例化对象的类型。 问题 假设你正在开发一款物流管理应用。 最初版本只能处理卡车…

单目标应用:蜣螂优化算法DBO与麻雀搜索算法SSA求解无人机三维航迹规划(提供Matlab代码)

一、无人机三维航迹规划 三维航迹规划是无人机在执行任务过程中的非常关键的环节&#xff0c;三维航迹规划的主要目的是在满足任务需求和自主飞行约束的基础上&#xff0c;计算出发点和目标点之间的最佳航路。 1.1路径最短约束 无人机航迹规划的首要目标是寻找起飞点和目标点…

一文搞定visual studio code远程服务器的配置和文件上传

在跑大型程序的时候需要用到服务器&#xff0c;因此如何远程操作服务器就至关重要了。 很多教程教如何使用putty来操作&#xff0c;但是我的安装时候就出现错误了。再加上我用的visual studio code提供远程服务器控制以及文件传输功能。 因此我就使用vscode来配置相应的环境并…

Unity学习笔记--FixedUpdate真的是固定时间调用一次吗?

前言 我相信大家在学习Unity的时候&#xff0c;Update是每一帧调用&#xff0c;而FixedUpdate是固定时间调用一次。 一开始我们对这个知识深信不疑&#xff08;楼主也是 .| &#xff09; 不过当我们学的更深入时&#xff0c;发现Unity其实是单线程的&#xff0c;所以它的生命…

解决d2l包下载不了的问题

目录 关于d2l包 1、在pypi网站的找到d2l包 2、cmd下载文件 3、检测d2l包的下载是否成功 4、在虚拟环境中完成安装 关于d2l包 d2l包是李沐老师等人开发的《动手深度学习》配套的包&#xff0c;最初的时候&#xff0c;我并没有安装的想法&#xff0c;可在代码实现方面&…

如何使用 max_fanout

在 逻辑层级不多&#xff0c;但是延时较高的 net 中&#xff0c;可以使用 max_fanout 来设置扇出&#xff0c; 但是要注意&#xff0c;还要如果驱动与负载不在同一层&#xff0c;一定要约束到负载的input&#xff0c;否则不生效 并且还要在 例化负载模块时加上 (* keep_hiera…

nacos安装及配置

本文介绍nacos的安装、配置&#xff0c;使用mysql存储数据。 1.下载 在github上下载对应的压缩包。地址&#xff1a;https://github.com/alibaba/nacos/releases 本文下载的是2.0.2版本&#xff1a; 2.解压 进入下载文件所在的目录&#xff0c;并执行以下语句&#xff1a; t…

GEE10:Earth Engine Reducers的图像矢栅转换及区域统计

目录1. Raster to Vector Conversion&#xff1a;image.reduceToVectors()2. Vector to Raster Conversion&#xff1a;featureCollection.reduceToImage()3. Grouped reductions3.1 Grouped reduceRegions (aka Zonal Statistics)4. Weighted Reductions1. Raster to Vector C…

SSM整合案例[企业权限管理系统]-学习笔记01【SVN的基本介绍】

Java后端-学习路线-笔记汇总表【黑马程序员】SSM整合案例[企业权限管理系统]-学习笔记01【SVN的基本介绍】【day01】SSM整合案例[企业权限管理系统]-学习笔记02【TortoiseSVN的基本操作】SSM整合案例[企业权限管理系统]-学习笔记03【TortoiseSVN及IDEA下SVN的使用】SSM整合案例…

四旋翼无人机学习第21节--allergo软件中的元器件高亮显示与丝印3D显示设置

1 allergo软件中的元器件高亮显示 在设计PCB的时候&#xff0c;会出现元器件高亮的情况&#xff0c;并且在项目重启后&#xff0c;这种现象依然存在。现在终于找到了原因的所以。点击高亮的元器件&#xff0c;右键选择选择Dehighlight即可。 取消高亮后的元器件显示。 2 解决…

已解决Building wheels for collected packages: lxml

已解决&#xff08;pip安装第三方模块lxml模块报错&#xff09;Building wheels for collected packages: lxml Building wheel for lxml (setup.py) … error error: subprocess-exited-with-error python setup.py bdist_wheel did not run successfully. note: This error o…