以下是核心代码:
设置中文字体支持
self.font = ("SimHei", 10)
# APK文件路径
self.apk_path = tk.StringVar()
self.create_widgets()
# 确保D:/apk目录存在
self.ensure_apk_dir()
def ensure_apk_dir(self):
"""确保D:/apk目录存在"""
try:
if not os.path.exists("D:/apk"):
os.makedirs("D:/apk")
except Exception as e:
messagebox.showerror("错误", f"无法创建临时工作目录: {str(e)}")
def create_widgets(self):
"""创建GUI组件"""
# 标题
title_label = tk.Label(self.root, text="APK解包工具", font=("SimHei", 16, "bold"))
title_label.pack(pady=20)
# APK文件选择区域
apk_frame = tk.Frame(self.root)
apk_frame.pack(fill=tk.X, padx=50, pady=10)
tk.Label(apk_frame, text="APK文件:", font=self.font).pack(side=tk.LEFT, padx=5)
apk_entry = tk.Entry(apk_frame, textvariable=self.apk_path, width=40, font=self.font)
apk_entry.pack(side=tk.LEFT, padx=5)
browse_apk_btn = tk.Button(apk_frame, text="浏览...", command=self.browse_apk, font=self.font)
browse_apk_btn.pack(side=tk.LEFT, padx=5)
# 红色提示文字
red_tip_label = tk.Label(
self.root,
text="解包后文件夹默认保存为桌面",
font=("SimHei", 10, "bold"),
fg="red"
)
red_tip_label.pack(pady=10)
# 进度条区域
progress_frame = tk.Frame(self.root)
progress_frame.pack(fill=tk.X, padx=50, pady=10)
self.progress_var = tk.DoubleVar()
self.progress_bar = ttk.Progressbar(
progress_frame,
variable=self.progress_var,
maximum=100,
length=500
)
self.progress_bar.pack(side=tk.LEFT, padx=5)
self.progress_label = tk.Label(progress_frame, text="0%", font=self.font, width=5)
self.progress_label.pack(side=tk.LEFT, padx=5)
# 辅助提示信息
tip_label = tk.Label(
self.root,
text="提示: 解包过程中会使用临时目录,完成后将自动清理",
font=self.font,
fg="#666666"
)
tip_label.pack(pady=5)
# 解包按钮
unpack_btn = tk.Button(
self.root,
text="开始解包",
command=self.unpack_apk,
font=("SimHei", 12),
width=15,
height=2,
bg="#4CAF50",
fg="white"
)
unpack_btn.pack(pady=20)
# 状态标签
self.status_var = tk.StringVar()
self.status_var.set("就绪")
status_label = tk.Label(self.root, textvariable=self.status_var, font=self.font, fg="#333333")
status_label.pack(pady=5)
def browse_apk(self):
"""浏览选择APK文件"""
file_path = filedialog.askopenfilename(
title="选择APK文件",
filetypes=[("APK文件", "*.apk"), ("所有文件", "*.*")]
)
if file_path:
self.apk_path.set(file_path)
def update_progress(self, value):
"""更新进度条,确保不超过100%"""
progress = min(value, 100)
self.progress_var.set(progress)
self.progress_label.config(text=f"{int(progress)}%")
self.root.update_idletasks() # 刷新界面
def clean_apk_dir(self):
"""清理D:/apk目录下的所有文件和文件夹"""
try:
if os.path.exists("D:/apk"):
for item in os.listdir("D:/apk"):
item_path = os.path.join("D:/apk", item)
try:
if os.path.isfile(item_path) or os.path.islink(item_path):
os.unlink(item_path)
elif os.path.isdir(item_path):
shutil.rmtree(item_path)
except Exception as e:
messagebox.showwarning("警告", f"清理临时文件时出错: {str(e)}")
except Exception as e:
messagebox.showwarning("警告", f"临时目录清理失败: {str(e)}")
def get_total_files(self, directory):
"""计算目录中文件的总数(不包括目录本身)"""
total = 0
for root, dirs, files in os.walk(directory):
total += len(files)
return total
def copy_with_progress(self, src, dst, total_files, start_progress, end_progress):
"""带进度的文件复制函数"""
copied = 0
progress_range = end_progress - start_progress
def copy_files(src, dst):
nonlocal copied
if os.path.isdir(src):
# 确保目标目录存在
if not os.path.exists(dst):
os.makedirs(dst)
# 复制目录中的所有项目
for item in os.listdir(src):
src_item = os.path.join(src, item)
dst_item = os.path.join(dst, item)
copy_files(src_item, dst_item)
else:
# 复制文件
shutil.copy2(src, dst)
copied += 1
# 计算进度(确保不会超过设定的结束进度)
progress = start_progress + (copied / total_files) * progress_range
self.update_progress(progress)
copy_files(src, dst)
# 确保最终进度达到结束进度
self.update_progress(end_progress)
def unpack_apk(self):
"""解包APK文件的主函数"""
apk_path = self.apk_path.get()
# 重置进度条
self.update_progress(0)
# 验证输入
if not apk_path:
messagebox.showerror("错误", "请选择APK文件")
return
if not os.path.exists(apk_path):
messagebox.showerror("错误", "所选APK文件不存在")
return
try:
# 获取APK文件名(不含扩展名)
apk_filename = os.path.basename(apk_path)
apk_name = os.path.splitext(apk_filename)[0]
# 临时解压目录
temp_target_path = os.path.join("D:/apk", apk_name)
# 桌面最终目录
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
final_target_path = os.path.join(desktop_path, apk_name)
# 更新状态
self.status_var.set("正在处理...")
self.root.update()
# 创建临时ZIP文件路径
zip_path = os.path.join("D:/apk", f"{apk_name}.zip")
# 复制APK文件并重命名为ZIP
shutil.copy2(apk_path, zip_path)
self.status_var.set("已转换为压缩文件,正在解压...")
self.root.update()
# 解压ZIP文件(带进度)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
# 获取所有文件信息
file_list = zip_ref.infolist()
total_files = len(file_list)
if total_files == 0:
messagebox.showerror("错误", "APK文件为空或损坏")
return
# 确保临时目录存在
os.makedirs(temp_target_path, exist_ok=True)
# 逐个解压文件并更新进度(占70%进度)
for i, file_info in enumerate(file_list, 1):
zip_ref.extract(file_info, temp_target_path)
progress = (i / total_files) * 70 # 限制在70%以内
self.update_progress(progress)
# 准备复制到桌面
self.status_var.set("正在复制到桌面...")
self.root.update()
# 如果桌面文件夹已存在,先删除
if os.path.exists(final_target_path):
shutil.rmtree(final_target_path)
# 计算总文件数用于进度显示
total_copy_files = self.get_total_files(temp_target_path)
if total_copy_files == 0:
messagebox.showerror("错误", "解压后的文件夹为空")
return
# 执行带进度的复制(占30%进度,从70%到100%)
self.copy_with_progress(temp_target_path, final_target_path, total_copy_files, 70, 100)
# 清理临时文件和D:/apk目录
self.status_var.set("正在清理临时文件...")
self.root.update()
# 先删除临时ZIP文件
if os.path.exists(zip_path):
os.remove(zip_path)
# 清理D:/apk目录下的所有内容
self.clean_apk_dir()
# 进度条完成
self.update_progress(100)
# 更新状态并显示成功信息
self.status_var.set("解包完成")
messagebox.showinfo(
"成功",
f"APK解包成功!\n\n文件已保存到桌面的「{apk_name}」文件夹中。"
)
except PermissionError:
self.status_var.set("解包失败")
messagebox.showerror("权限错误", "没有足够的权限操作文件,请以管理员身份运行")
except Exception as e:
self.status_var.set("解包失败")
messagebox.showerror("错误", f"解包过程中发生错误: {str(e)}")
成品下载:https://wwcq.lanzouu.com/ieR3Z39dgptg 密码:54g3,感谢支持!
有任何问题评论区反馈谢谢。

