序言
在开发工作中,有时候需要构造高负载环境,需要安装一些大型的游戏应用。比如和平精英。和平精英的安装器有1.9G 但是安装完之后,还需要下载7G左右的内容。每次花费大量时间。写了一个备份apk的工具。
使用
命令

备份内容
每个 .apk_backup 是一个 未压缩 tar 包(大体积备份更快),内含:
apks/ --- 所有 APK 分包
obb/ --- OBB 目录(有数据才包含)
data/ --- /sdcard/Android/data/<包名>/ 内容
package.txt --- 包名(恢复时优先读取)
使用示例
bash
app_backup com.tencent.tmgp.pubgmhd
app_backup -restore com.tencent.tmgp.pubgmhd.apk_backup
源文件
app_backup.bat
c
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
where adb >nul 2>nul
if errorlevel 1 (
echo 错误:未找到 adb 命令,请确保 Android SDK 已安装并配置环境变量。
pause
exit /b 1
)
adb get-state >nul 2>nul
if errorlevel 1 (
echo 错误:未检测到已连接的设备,请连接手机并开启 USB 调试。
pause
exit /b 1
)
if "%1"=="" goto :usage
if /i "%1"=="-h" goto :usage
if /i "%1"=="--help" goto :usage
if /i "%1"=="help" goto :usage
if /i "%1"=="-restore" goto :do_restore
if /i "%1"=="-resotre" goto :do_restore
set PACKAGE=%1
call :backup "%PACKAGE%"
goto :eof
:do_restore
if "%2"=="" (
echo 错误:请指定要恢复的 .apk_backup 文件。
goto :usage
)
call :restore "%~2"
goto :eof
:usage
echo 用法:
echo app_backup ^<包名^> 备份应用(APK + OBB + data)
echo app_backup -restore ^<文件.apk_backup^> 从备份恢复
echo.
echo 示例:
echo app_backup com.tencent.tmgp.pubgmhd
echo app_backup -restore com.tencent.tmgp.pubgmhd.apk_backup
pause
exit /b 0
:backup
set "PACKAGE=%~1"
echo ========================================
echo 正在备份 %PACKAGE%
echo ========================================
echo.
set "TEMP_DIR=%TEMP%\%PACKAGE%_backup_%RANDOM%"
set "SCRIPT_DIR=%~dp0"
set "BACKUP_FILE=%SCRIPT_DIR%%PACKAGE%.apk_backup"
mkdir "%TEMP_DIR%" 2>nul
if not exist "%TEMP_DIR%" (
echo 错误:无法创建临时目录。
pause
exit /b 1
)
cd /d "%TEMP_DIR%"
echo [1/5] 获取 APK 路径...
set APK_COUNT=0
for /f "usebackq tokens=1,* delims=:" %%a in (`adb shell pm path %PACKAGE% 2^>nul`) do (
if /i "%%a"=="package" (
set /a APK_COUNT+=1
set "APK_PATH_!APK_COUNT!=%%b"
)
)
if !APK_COUNT! equ 0 (
echo 错误:找不到包 %PACKAGE%,请检查包名或应用是否已安装。
call :cleanup_temp "%TEMP_DIR%"
pause
exit /b 1
)
echo 发现 !APK_COUNT! 个 APK 分包
echo [2/5] 拉取 APK 文件...
mkdir "apks" 2>nul
set IDX=0
for /l %%n in (1,1,!APK_COUNT!) do (
set /a IDX+=1
set "SRC=!APK_PATH_%%n!"
if "!SRC:~0,1!"==" " set "SRC=!SRC:~1!"
for %%f in ("!SRC!") do set "APK_NAME=%%~nxf"
echo 拉取 !APK_NAME! ...
adb pull "!SRC!" "apks\!APK_NAME!"
if errorlevel 1 (
echo 错误:拉取 APK 失败:!SRC!
call :cleanup_temp "%TEMP_DIR%"
pause
exit /b 1
)
)
echo [3/5] 拉取 OBB 目录...
set "OBB_DIR=/sdcard/Android/obb/%PACKAGE%"
adb shell "[ -d '%OBB_DIR%' ] && ls -A '%OBB_DIR%' 2>/dev/null | grep -q . && echo has_files || echo empty" 2>nul | findstr /i "has_files" >nul
if not errorlevel 1 (
echo 源路径: %OBB_DIR%
echo 数据较大时请耐心等待...
adb pull "%OBB_DIR%" "obb"
if errorlevel 1 (
echo 警告:拉取 OBB 失败,跳过。
rmdir /s /q "obb" 2>nul
) else (
echo OBB 已备份。
)
) else (
echo 无 OBB 数据,跳过。
)
echo [4/5] 拉取 data 目录...
set "DATA_DIR=/sdcard/Android/data/%PACKAGE%"
adb shell "[ -d '%DATA_DIR%' ] && ls -A '%DATA_DIR%' 2>/dev/null | grep -q . && echo has_files || echo empty" 2>nul | findstr /i "has_files" >nul
if not errorlevel 1 (
echo 源路径: %DATA_DIR%
echo 数据较大时请耐心等待...
adb pull "%DATA_DIR%" "data"
if errorlevel 1 (
echo 警告:拉取 data 失败,跳过。
rmdir /s /q "data" 2>nul
) else (
echo data 已备份。
)
) else (
echo 无 data 数据,跳过。
)
echo %PACKAGE%> package.txt
echo [5/5] 打包为 %PACKAGE%.apk_backup ...
if exist "%BACKUP_FILE%" del /f /q "%BACKUP_FILE%"
tar -cf "%BACKUP_FILE%" *
if errorlevel 1 (
echo 错误:打包失败,请确保系统支持 tar 命令(Windows 10 及以上)。
call :cleanup_temp "%TEMP_DIR%"
pause
exit /b 1
)
for %%A in ("%BACKUP_FILE%") do set "BACKUP_SIZE_STR=%%~zA bytes"
call :cleanup_temp "%TEMP_DIR%"
echo.
echo ========================================
echo 备份完成!
echo 文件: !BACKUP_FILE!
echo 大小: !BACKUP_SIZE_STR!
echo ========================================
exit /b 0
:restore
set "BACKUP_FILE=%~f1"
if not exist "%BACKUP_FILE%" (
echo 错误:找不到备份文件 %BACKUP_FILE%
pause
exit /b 1
)
echo ========================================
echo 正在从备份恢复
echo 文件: "!BACKUP_FILE!"
echo ========================================
echo.
set "RESTORE_DIR=%TEMP%\restore_%RANDOM%"
mkdir "%RESTORE_DIR%" 2>nul
cd /d "%RESTORE_DIR%"
echo [1/5] 解压备份...
tar -xf "%BACKUP_FILE%"
if errorlevel 1 (
echo 错误:解压失败,文件可能损坏。
call :cleanup_temp "%RESTORE_DIR%"
pause
exit /b 1
)
set "PACKAGE="
if exist "package.txt" (
set /p PACKAGE=<package.txt
)
if "!PACKAGE!"=="" (
set "FNAME=%~n1"
if /i "!FNAME:~-11!"==".apk_backup" (
set "PACKAGE=!FNAME:~0,-11!"
) else (
set "PACKAGE=!FNAME!"
)
)
if "!PACKAGE!"=="" (
echo 错误:无法确定包名,请检查备份文件。
call :cleanup_temp "%RESTORE_DIR%"
pause
exit /b 1
)
echo 目标包名:!PACKAGE!
echo.
echo [2/5] 停止应用...
adb shell am force-stop !PACKAGE! 2>nul
echo [3/5] 安装 APK...
set "INSTALL_OK=0"
if exist "apks" (
set APK_INSTALL_COUNT=0
for %%f in (apks\*.apk) do set /a APK_INSTALL_COUNT+=1
if !APK_INSTALL_COUNT! gtr 1 (
echo 检测到 !APK_INSTALL_COUNT! 个分包,使用 install-multiple...
set "INSTALL_CMD=adb install-multiple -r -d"
for %%f in (apks\*.apk) do set "INSTALL_CMD=!INSTALL_CMD! apks\%%~nxf"
!INSTALL_CMD!
) else if exist "apks\base.apk" (
adb install -r -d "apks\base.apk"
) else (
for %%f in (apks\*.apk) do adb install -r -d "%%f"
)
if not errorlevel 1 set "INSTALL_OK=1"
) else if exist "base.apk" (
adb install -r -d "base.apk"
if not errorlevel 1 set "INSTALL_OK=1"
) else (
echo 错误:备份中没有 APK 文件。
call :cleanup_temp "%RESTORE_DIR%"
pause
exit /b 1
)
if "!INSTALL_OK!"=="1" (
echo APK 安装成功。
) else (
echo 警告:APK 安装失败,可能签名冲突。请手动安装后继续恢复数据。
)
echo [4/5] 恢复 OBB...
if exist "obb" (
adb shell "mkdir -p '/sdcard/Android/obb/!PACKAGE!'" 2>nul
adb shell "rm -rf '/sdcard/Android/obb/!PACKAGE!/'*" 2>nul
echo 推送至 /sdcard/Android/obb/!PACKAGE!/ ...
adb push "obb" "/sdcard/Android/obb/!PACKAGE!/"
if errorlevel 1 (
echo 警告:OBB 恢复失败。
) else (
echo OBB 恢复完成。
)
) else (
echo 备份中无 OBB,跳过。
)
echo [5/5] 恢复 data...
if exist "data" (
adb shell "mkdir -p '/sdcard/Android/data/!PACKAGE!'" 2>nul
adb shell "rm -rf '/sdcard/Android/data/!PACKAGE!/'*" 2>nul
echo 推送至 /sdcard/Android/data/!PACKAGE!/ ...
adb push "data" "/sdcard/Android/data/!PACKAGE!/"
if errorlevel 1 (
echo 警告:data 恢复失败。
) else (
echo data 恢复完成。
)
) else (
echo 备份中无 data,跳过。
)
call :cleanup_temp "%RESTORE_DIR%"
echo.
echo ========================================
echo 恢复完成!请手动启动应用检查数据。
echo ========================================
exit /b 0
:cleanup_temp
cd /d "%~dp0"
if not "%~1"=="" rmdir /s /q "%~1" 2>nul
exit /b 0
效果
