Python实现Android自动化打包工具:加固、签名、多渠道一键完成

一、项目背景

在Android应用开发流程中,打包发布是必不可少的环节。传统的打包方式需要手动执行多个步骤:

  1. APK加固 - 使用第三方服务保护代码

  2. APK签名 - 使用apksigner进行V1/V2/V3签名

  3. 多渠道打包 - 为不同应用市场生成渠道包

这些操作繁琐且容易出错,因此我开发了这个基于Python Tkinter的自动化打包工具,实现一键完成所有操作。

二、功能特性

🎯 核心功能

复制代码
| 功能模块 | 说明 | 技术实现 |

|---------|------|---------|

| **APK加固** | 集成阿里云mPaaS专业版加固 | 调用msaEnhance模块 |

| **APK签名** | 支持V1/V2/V3多版本签名 | 使用apksigner工具 |

| **多渠道打包** | 支持15+主流应用市场渠道 | 自定义渠道信息注入 |

| **日志系统** | 实时显示打包进度和结果 | 线程安全队列机制 |

✨ 特色亮点

·自动化流程:选择APK后一键完成加固→签名→多渠道打包

·多应用支持:内置5个应用配置,自动识别包名

·渠道多选:支持全选/反选,灵活选择目标渠道

·现代UI:简洁美观的Tkinter图形界面

三、项目结构与核心代码

3.1 项目架构

├── android_package_tool.py # 主界面入口(Tkinter)

├── msaEnhance.py # 阿里云mPaaS加固模块

├── apkSign.py # APK签名模块(apksigner)

├── apkInfo.py # APK信息解析(aapt工具)

└── androidPackage.py # 渠道打包模块

3.2 核心代码解析

🔹 线程安全日志系统

python 复制代码
def _process_log_queue(self):
        """处理日志队列,定时从队列中读取日志并显示"""
        try:
            while True:
                msg = self.log_queue.get_nowait()
                # 检查是否是特殊的"完成"标记
                if msg == "_TASK_COMPLETED_":
                    self._on_task_completed()
                else:
                    timestamp = self._get_time()
                    log_line = f"[{timestamp}] {msg}\n"
                    self.log_text.insert(tk.END, log_line)
                    self.log_text.see(tk.END)
        except queue.Empty:
            pass
        self.root.after(100, self._process_log_queue)

设计思路:使用`queue.Queue`实现线程安全的日志更新,避免子线程直接操作UI控件导致的线程安全问题。

🔹 多应用配置管理

python 复制代码
apk_package_info = {

    "package_name_1": "app_name_1",

    "package_name_2": "app_name_2",

    "package_name_3": "app_name_3",

    "package_name_4": "app_name_4",

    "package_name_5": "app_name_5"

}

设计思路:通过字典映射实现多应用的配置管理,选择APK后自动识别包名并加载对应配置。

🔹 渠道选择实现

python 复制代码
self.channel_options = [
            ('OGC', '官方'),
            ('LXS', '联想'),
            ('XMS', '小米'),
            ('BDS', '百度'),
            ('YYB', '应用宝'),
            ('QHS', '360'),
            ('WZJ', '豌豆荚'),
            ('RYS', '荣耀'),
            ('OPS', 'OPPO'),
            ('YYH', '应用汇'),
            ('KPS', '酷派'),
            ('HWS', '华为'),
            ('MZS', '魅族'),
            ('SXS', '三星'),
            ('VVS', 'VIVO')
        ]
        # 存储选中的渠道(默认选中所有)
        self.selected_channels = {code: tk.BooleanVar(value=True) for code, _ in self.channel_options}
        # 创建渠道代号到名称的映射字典
        self.channel_map = {code: name for code, name in self.channel_options}

设计思路:使用`BooleanVar`动态绑定复选框状态,支持全选/反选功能。

🔹 异步任务执行

python 复制代码
def _start_process(self):
        apk_path = self.apk_path.get().strip()
        if not apk_path or not os.path.exists(apk_path):
            self._log("错误:请选择有效的APK文件")
            return

        if self.is_processing:
            self._log("正在处理中...")
            return

        enhance = self.is_enhance.get()
        sign = self.is_sign.get()
        
        # 获取选中的渠道列表
        selected = [code for code, var in self.selected_channels.items() if var.get()]
        if not selected:
            self._log("错误:请至少选择一个渠道")
            return
        
        channels_str = ", ".join(selected)

        self._log(f"开始处理: {os.path.basename(apk_path)}")
        self._log(f"加固: {'是' if enhance else '否'}, 签名: {'是' if sign else '否'}")
        self._log(f"选中渠道: {channels_str}")

        self.is_processing = True
        self.btn_start.config(state="disabled")
        self.progress_bar.start()

        # 使用非守护线程执行任务
        thread = threading.Thread(target=self._execute, args=(apk_path, enhance, sign, selected))
        thread.start()

设计思路:将耗时操作放在子线程中执行,避免阻塞UI主线程。

四、核心执行流程

选择APK → 解析APK信息 → 识别应用配置

执行加固(可选)→ msaEnhance.excute_whole_flow()

执行签名(可选)→ ApkSigner.sign_apk()

多渠道打包 → 循环调用androidPackage.build_single_apk()

任务完成 → 更新UI状态

关键代码:执行流程

python 复制代码
def _execute(self, apk_path, enhance, sign, channels):
        try:
            enhance_output_apk = None  # 初始化变量
            sign_output_apk = None  # 初始化变量
            
            if enhance:
                self._log("执行加固...")
                try:
                    file_name = apk_path.split("/")[-1]
                    output_name = file_name.replace(".apk", "_enhanced.apk")
                    enhance_output_apk = apk_path.replace(os.path.basename(apk_path), output_name)
                    if not enhance_output_apk:
                        enhance_output_apk = "enhanced_apk.apk"
                    msaEnhance.set_config(app_package_name=self.package_name.get(), local_apk=apk_path, output_apk=enhance_output_apk)
                    msaEnhance.excute_whole_flow()
                    self._log("加固完成")
                except Exception as e:
                    self._log(f"加固失败: {str(e)}")
                    import traceback
                    self._log(traceback.format_exc())

            if sign:
                self._log("执行签名...")
                try:
                    self._log("初始化签名工具...")
                    signer = ApkSigner()
                    signer.set_app(app_package_name=self.package_name.get())
                    # 如果没有执行加固,使用原始APK路径
                    input_apk = enhance_output_apk if enhance_output_apk else apk_path
                    sign_file_name = input_apk.split("/")[-1]
                    sign_output_name = sign_file_name.replace(".apk", "_signed.apk")
                    sign_output_apk = input_apk.replace(os.path.basename(input_apk), sign_output_name)
                    if not sign_output_apk:
                        sign_output_apk = "enhanced_signed_apk.apk"
                    signer.set_config(input_apk=input_apk, output_apk=sign_output_apk)
                    self._log("签名工具初始化完成")
                    signer.sign_apk()
                    self._log("签名完成")
                except Exception as e:
                    self._log(f"签名失败: {str(e)}")
                    import traceback
                    self._log(traceback.format_exc())

            # 处理多个渠道
            # 确定要使用的APK:签名后的 > 加固后的 > 原始的
            channel_input_apk = sign_output_apk if sign_output_apk else (enhance_output_apk if enhance_output_apk else apk_path)
            
            self._log(f"开始生成渠道包 ({len(channels)} 个渠道)")
            for idx, channel in enumerate(channels, 1):
                self._log(f"  [{idx}/{len(channels)}] 渠道: {channel}")
                try:
                    channel_id = channel
                    channel_name = self.channel_map.get(channel, channel)
                    
                    log_message = f'------开始打包渠道号 {idx}/{len(channels)}------\n'
                    log_message += '渠道号:%s\n' % channel_id
                    log_message += '渠道名:%s\n' % channel_name
                
                    result = androidPackage.build_single_apk(channel_id, channel_name, channel_input_apk)
                    self._log(log_message)
                    self._log(f"✅ 渠道 {channel} 包生成成功: {result}")
                except Exception as e:
                    self._log(f"❌ 渠道 {channel} 包生成失败: {str(e)}")
                    import traceback
                    self._log(traceback.format_exc())
            
            self._log("✅ 处理完成!")

        except Exception as e:
            self._log(f"❌ 执行错误: {str(e)}")
            import traceback
            self._log(traceback.format_exc())

        finally:
            # 通过日志队列发送任务完成信号(线程安全)
            self._log("_TASK_COMPLETED_")

五、界面设计

5.1 主界面布局

5.2 界面优化要点

| 优化项 | 实现方式 |

| 渠道布局 | 每行4个复选框,紧凑排列 |

| 按钮区域 | 居中分布,间距均匀 |

| 日志窗口 | 自适应高度,填充剩余空间 |

| 版本信息 | 动态获取当前年份 |

六、技术亮点总结

6.1 线程安全设计

  • 使用队列实现日志的线程安全更新

  • 子线程通过队列发送"任务完成"信号

  • 主线程通过`after()`方法定时处理队列

6.2 模块化架构

  • 各功能模块独立封装

  • 通过回调函数实现日志集成

  • 支持动态配置和扩展

6.3 用户体验优化

  • 自动识别应用配置

  • 支持渠道多选和快捷操作

  • 实时进度展示和日志输出

七、使用指南

7.1 环境要求

复制代码
# 依赖组件

Python 3.x # 开发语言

Tkinter # UI框架(Python内置)

Android SDK # 含aapt、apksigner工具

阿里云mPaaS账号 # 加固服务

7.2 快速开始

运行工具

python android_package_tool.py

操作步骤

  1. 点击「浏览」选择APK文件

  2. 勾选需要的操作(加固/签名)

  3. 选择目标渠道(默认全选)

  4. 点击「开始」执行打包流程

八、总结

这个Android打包工具通过Python实现了自动化打包流程,主要优势:

  • 高效:一键完成加固、签名、多渠道打包

  • 稳定:线程安全的日志系统,避免UI卡顿

  • 灵活:支持多应用配置和渠道自定义

  • 易用:直观的图形界面,降低使用门槛

相关推荐
天天进步20151 小时前
从零打造 Python 全栈项目:智能教学辅助系统
开发语言·人工智能·python
带带弟弟学爬虫__1 小时前
dyAPP数据采集-个人主页、发布、搜索、评论
服务器·python·算法·flutter·java-ee·django
还是鼠鼠1 小时前
AI掘金头条新闻系统 (Toutiao News)-相关推荐
后端·python·mysql·fastapi·web
QING6182 小时前
Kotlin inline 实战详解 —— 新手须知
android·kotlin·android jetpack
ccice012 小时前
硬核教程:用Gemini编排多任务办公智能体,实现周报、数据表与行程单全自动生成(国内免费镜像方案)
人工智能·自动化
ElevenS_it1882 小时前
MySQL慢查询监控与告警实战:从slow_log采集到分钟级定位慢SQL的完整链路配置
android·sql·mysql
数智工坊2 小时前
PyCharm 运行 Python 脚本总自动进 Test 模式?附 RT-DETRv2 依赖缺失终极排坑
开发语言·ide·人工智能·python·pycharm
沐言人生2 小时前
ReactNative 源码分析12——Native View创建流程onBatchComplete
android·react native
caicai_xiaobai2 小时前
QT搭建安卓开发环境
android