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

Posted la_vie_est_belle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Buildozer打包实战指南》第四节 正式打包一个apk文件相关的知识,希望对你有一定的参考价值。

目录

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文件。

在模拟器中也运行成功。

以上是关于《Buildozer打包实战指南》第四节 正式打包一个apk文件的主要内容,如果未能解决你的问题,请参考以下文章

《Nuitka打包实战指南》第四节 先调试再发布

《Buildozer打包实战指南》实战打包requests

《Buildozer打包实战指南》实战打包pillow

《Buildozer打包实战指南》实战打包pillow

《Buildozer打包实战指南》实战打包numpy

《Buildozer打包实战指南》实战打包requests