APK安装和卸载的基本流程
APK 安装流程
graph TD
A[开始安装] --> B[复制APK到临时目录]
B --> C[解析AndroidManifest.xml]
C --> D[验证签名]
D --> E[检查系统版本和权限]
E --> F[创建应用数据目录]
F --> G[拷贝APK到系统目录]
G --> H[更新系统包数据库]
H --> I[发送安装完成广播]
I --> J[结束安装]
主要步骤:
- 复制 APK 到
/data/local/tmp/
- 解析清单文件,验证签名和权限
- 创建应用数据目录
- 拷贝 APK 到
/data/app/
- 更新包数据库,发送广播
APK 卸载流程
graph TD
A[开始卸载] --> B[停止应用进程]
B --> C[删除应用数据目录]
C --> D[删除系统目录中的APK]
D --> E[更新系统包数据库]
E --> F[发送卸载完成广播]
F --> G[结束卸载]
主要步骤:
- 停止应用所有进程
- 删除
/data/data/包名
目录 - 删除
/data/app/
中的 APK - 更新系统数据库
- 发送卸载完成广播
关键目录
/data/app/
: APK 存储目录/data/data/
: 应用数据目录/data/dalvik-cache/
: 优化后的 dex 文件
这就是 Android APK 安装卸载的核心流程,实际过程中还会涉及更多细节,如权限检查、签名验证等。
APK瘦身优化方向
1. 🗜️ 资源优化
1.1 图片资源优化
android {
// 启用 PNG 压缩
aaptOptions {
cruncherEnabled = true
}
}
-
图片格式选择
- 🔄 将 PNG 转换为 WebP
cwebp -q 75 image.png -o image.webp
- 🎨 使用 SVG 替代多个分辨率的图片
- 📊 合理使用 9-patch 图片
-
图片压缩工具
- 使用
tinypng
pngquant
ImageOptim
Compress.io
- 使用
-
矢量图使用
<!-- vector drawable -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
</vector>
1.2 资源文件优化
- 移除未使用资源
android {
buildTypes {
release {
shrinkResources true
minifyEnabled true
}
}
}
- 资源文件分包
android {
// splits 用于配置 APK 分包策略
splits {
// density 配置密度分包,即针对不同屏幕密度生成不同的 APK
density {
// 启用密度分包功能
enable true
// 排除指定密度的资源文件,这些密度的设备将使用更高密度的资源进行缩放
// ldpi: 低密度屏幕 (120dpi)
// mdpi: 中等密度屏幕 (160dpi)
exclude "ldpi", "mdpi"
// 指定兼容的屏幕尺寸
// normal: 正常尺寸屏幕 (~470dp x ~320dp)
// large: 大尺寸屏幕 (~640dp x ~480dp)
// xlarge: 超大尺寸屏幕 (~960dp x ~720dp)
compatibleScreens 'normal', 'large', 'xlarge'
}
}
}
- 语言资源优化
android {
defaultConfig {
resConfigs "zh", "en"
}
}
2. 📦 代码优化
2.1 ProGuard 配置
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
}
- 自定义 ProGuard 规则
# 保留某些类
-keep class com.example.important.** { *; }
# 移除日志
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
}
2.2 R8 优化
android {
buildTypes {
release {
// 启用 R8
minifyEnabled true
// 启用 R8 完全模式
useProguard false
}
}
}
3. 🎯 动态化方案
3.1 动态功能模块
// 动态特性模块
dynamic-feature {
implementation project(":app")
}
- Play Core Library
val request = SplitInstallRequest.newBuilder()
.addModule("dynamic_feature")
.build()
splitInstallManager.startInstall(request)
- 按需加载
class DynamicFeatureActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 检查模块是否需要安装
if (splitInstallManager.installedModules.contains("dynamic_feature")) {
loadFeature()
} else {
installFeature()
}
}
}
4. 📱 SO 库优化
4.1 ABI 选择
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
4.2 动态加载
System.loadLibrary("native-lib")
5. 🛠️ 构建优化
5.1 启用 AndroidX
android {
useAndroidX = true
enableJetifier = true
}
5.2 依赖优化
dependencies {
// 使用精简版依赖
implementation 'com.google.android.material:material:1.5.0'
// 排除不需要的传递依赖
implementation('library') {
exclude group: 'com.unused', module: 'unused-module'
}
}
6. 🌐 网络资源优化
6.1 资源按需下载
class ResourceManager {
fun downloadResourcesIfNeeded() {
if (!isResourceDownloaded()) {
downloadResources()
}
}
}
6.2 CDN 加速
const val BASE_URL = "https://cdn.example.com/resources/"
7. 📊 监控与分析
7.1 APK Analyzer
# 使用命令行分析 APK
apkanalyzer size app-release.apk
7.2 自定义监控
class ApkSizeMonitor {
fun trackResourceSize() {
// 统计各类资源大小
}
}
8. 🎨 实践建议
- 资源命名规范
<!-- 统一命名规范 -->
<string name="feature_title">标题</string>
<dimen name="feature_margin">16dp</dimen>
- 代码复用
// 使用扩展函数减少代码重复
fun Context.dpToPx(dp: Float): Float {
return dp * resources.displayMetrics.density
}
- 懒加载实现
private val heavyResource by lazy {
// 延迟加载大资源
loadResource()
}
9. 📈 效果评估
9.1 大小对比
fun compareApkSize() {
val oldSize = getOldApkSize()
val newSize = getNewApkSize()
val reduction = oldSize - newSize
println("减少了 ${reduction}MB")
}
9.2 性能监控
class PerformanceMonitor {
fun trackStartupTime() {
val startTime = System.currentTimeMillis()
// 应用启动
val endTime = System.currentTimeMillis()
println("启动耗时:${endTime - startTime}ms")
}
}
10. 🎯 优化清单
-
编译期优化
- 启用 R8
- 配置 ProGuard
- 移除未使用资源
- 启用资源压缩
-
资源优化
- 图片压缩
- 资源文件整理
- 多语言优化
- 动态资源加载
-
代码优化
- 代码混淆
- 依赖优化
- 动态加载
- 代码复用
-
构建优化
- ABI 选择
- 依赖管理
- 构建变体
- 多渠道打包
11. 📝 优化效果评估
class OptimizationMetrics {
fun calculateMetrics() {
val metrics = mutableMapOf<String, Long>()
// 统计各项指标
metrics["apkSize"] = getApkSize()
metrics["startupTime"] = getStartupTime()
metrics["memoryUsage"] = getMemoryUsage()
// 输出报告
generateReport(metrics)
}
}
12. 🚀 持续优化建议
-
建立监控系统
- APK 大小趋势
- 启动时间监控
- 内存使用监控
- 崩溃率监控
-
优化流程规范
- 代码审查规范
- 资源提交规范
- 依赖管理规范
- 发布流程规范
-
团队协作
- 定期优化评审
- 技术分享
- 优化经验沉淀
- 工具链完善
通过以上这些方案的综合运用,可以有效地实现 APK 瘦身。记住,APK 瘦身是一个持续的过程,需要在开发过程中不断关注和优化。同时,要平衡好 APK 大小和应用功能之间的关系,确保在减小 APK 体积的同时不影响用户体验。