编程导航安卓话题讨论

安卓

14 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

有跟我一样从事安卓开发的兄弟不,有几个问题想咨询一下

现状:安卓开发,外包,负责车载的UI模块 问题: 1、询问一下有没有安卓的学习及深造路线,想请教一下如何在安卓这条道路上进一步深造; 2、大家都是如何把AI和安卓开发结合在一起,以提升工作效率的,或者说有没有什么相关的建议; 3、有没有推荐的书籍或网上教程协助安卓相关知识学习。如果能有复杂一点的项目,结合安卓最新前沿科技以及AI技术,那就更好了。

Android 应用包体积优化全面指南:从代码到资源的系统性优化策略

## 引言 随着移动应用功能的日益复杂化,Android 应用包体积不断增长已成为一个普遍问题。过大的应用包不仅影响用户下载转化率,还会增加存储占用、延长安装时间,并可能导致低端设备运行缓慢。根据 Google 官方数据,采用最新优化技术的应用可实现高达**50% 的体积缩减**,而采用 Android App Bundle 格式的应用平均减少**47% 的安装包体积**。 本指南将从代码优化、资源管理、依赖库精简等多个维度,全面剖析 Android 应用包体积优化的技术方法和实践策略。我们将重点关注 2025 年最新的技术进展,包括 Android Gradle Plugin 8.12.0 引入的革命性资源压缩优化、新一代图像格式 AVIF 的应用,以及各种前沿的优化工具和方法。 ## 一、代码层面优化策略 ### 1.1 R8 混淆压缩技术的深度应用 自 Android Gradle Plugin 3.4.0 版本起,**R8 已完全取代 ProGuard**成为默认的代码优化工具[(1)](https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com)。R8 将脱糖、压缩、混淆、优化和 dex 处理整合到一个步骤中,显著提升了构建性能[(90)](https://blog.csdn.net/fitaotao/article/details/115083963)。在 2025 年的最新版本中,R8 引入了多项革命性的优化特性。 **AGP 8.12.0 的革命性资源压缩优化**是当前最重要的技术突破。这一特性将代码优化与资源压缩合并处理,R8 能够同时处理代码和资源引用,智能识别那些只被无用代码引用的资源,并将它们连同对应的冗余代码一起移除[(77)](https://www.infoq.com/news/2025/09/android-optimized-R8/)。根据官方数据,对于跨不同形态因素共享大量资源和代码的应用,这种新方法可实现**超过 50% 的应用体积缩减**。 要启用这一功能,只需在 build.gradle 中配置: ``` android { &#x20; buildTypes { &#x20; release { &#x20; isMinifyEnabled = true &#x20; isShrinkResources = true &#x20; } &#x20; } } ``` 在 AGP 9.0 及更高版本中,这一行为将成为默认配置,无需额外设置 android.r8.optimizedResourceShrinking=true[(37)](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization?authuser=3\&hl=pt)。 **R8 的四大核心功能**为代码优化提供了全方位支持[(1)](https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com): 1. **代码压缩(Code Shrinking)**:通过静态代码分析查找和删除无法访问的代码和未实例化的类型,有效解决 64k 引用限制问题。R8 会从程序的入口点开始跟踪所有可访问的代码,然后使用摇树优化删除未使用的代码[(21)](https://blog.csdn.net/c10WTiybQ1Ye3/article/details/115682781)。 2. **资源压缩(Resource Shrinking)**:移除应用中未使用的资源文件,包括 res 文件夹和资源表中的无用资源。这一功能与代码压缩协同工作,当未使用的代码被删除后,所有不再被引用的资源也能被安全移除[(1)](https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com)。 3. **代码优化(Optimization)**:通过各种优化技术进一步减少代码体积并提升性能。这些技术包括: * **内联方法(Method Inlining)**:将小方法体直接插入调用处,减少方法调用开销,可提升运行时性能高达 30%[(1)](https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com) * **常量折叠和传播(Constant Folding and Propagation)**:简化数学表达式,用常量值替换变量 * **不可达代码消除(Unreachable Code Elimination)**:移除永远不会执行的代码路径 * **类合并(Class Merging)**:将相似的类或接口合并为单一实体[(87)](https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker) 1. **混淆(Obfuscation)**:缩短类和成员的名称,减少 DEX 文件大小。R8 使用简短、无意义的名称(如 a、b、c)替换原有的类名、方法名和字段名[(1)](https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com)。 **R8 的高级配置选项**提供了更精细的控制能力[(3)](https://developer.android.com/topic/performance/app-optimization/global-options?hl=ru): * **-repackageclasses**:将所有类重新打包到一个包中,通过去除包名前缀来减小 dex 文件大小 * **-allowaccessmodification**:允许 R8 修改类、字段和方法的可见性以执行更广泛的优化。从 AGP 8.2 开始,在 R8 全模式下默认启用 * **-dontoptimize**:阻止代码优化(如方法内联),仅在开发期间使用 * **-dontshrink**:阻止删除未使用的代码和优化 * **-dontobfuscate**:阻止缩短类和方法名称,有助于调试时阅读堆栈跟踪 ### 1.2 死代码消除与字节码优化 **死代码消除的深度配置**是代码优化的核心环节。R8 通过多种技术实现深度的死代码消除[(87)](https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker): 1. **摇树优化(Tree Shaking)**:使用静态代码分析查找和删除无法访问的代码和未实例化的类型。这是解决 64k 引用限制的有效工具,特别适用于只使用库的部分 API 的场景[(21)](https://blog.csdn.net/c10WTiybQ1Ye3/article/details/115682781)。 2. **条件优化**:当条件判断的结果可以确定时,死代码消除会移除未使用的分支,条件判断也会消失[(28)](https://jakewharton.com/r8-optimization-value-assumption/)。 3. **智能检测**:例如,当 R8 检测到某个 if/else 语句的 else 分支永远不会被执行时,会自动删除该分支代码[(1)](https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com)。 为了更好地理解 R8 的优化过程,以下是一个典型的优化流程图: ``` R8优化流程: 输入Class文件 → 压缩(可达性分析) → 移除未引用类/方法 &#x20; ↓ &#x20; 优化(字节码改写) → 方法内联、常量折叠等 &#x20; ↓ &#x20; 混淆(名称重命名) → 生成mapping.txt &#x20; ↓ 输出混淆后的Class文件 ``` **字节码优化的最新进展**令人振奋。2025 年 12 月,Android Runtime (ART) 团队实现了**编译时间 18% 的提升**,且不影响编译代码质量或峰值内存使用[(72)](https://android-developers.googleblog.com/2025/12/18-faster-compiles-0-compromises.html?m=1)。这一改进通过分阶段 rollout 实现,部分优化已在 2025 年 6 月发布,其余在年底完成,所有 Android 12 及以上版本用户都可通过 mainline 更新获得这些改进[(73)](https://carguo.blog.csdn.net/article/details/155972979)。 ### 1.3 代码精简与重构策略 **代码重构的最佳实践**需要遵循系统化的方法[(40)](https://blog.csdn.net/gitblog_00551/article/details/154564085): 1. **使用静态分析工具**:如 FindBugs、Lint 等检测代码中的 "坏味道",包括过长的函数、重复代码、未使用的变量等[(52)](https://edu.51cto.com/article/note/39630.html)。 2. **建立完善的测试覆盖**:这是安全重构的前提条件。为现有代码编写单元测试,确保重构不会改变功能[(44)](https://blog.51cto.com/u_12472724/14136468)。 3. **采用小步迭代方式**:每次只重构一小部分代码,确保每一步都能正常编译和运行。这种方法可以降低重构风险,及时发现问题[(40)](https://blog.csdn.net/gitblog_00551/article/details/154564085)。 4. **持续验证**:重构完成后,运行所有测试用例,确保功能完整性。 **代码复用与模块化设计**是减少代码体积的关键策略[(38)](https://blog.51cto.com/u_16213660/14316059): * 某社交应用团队采用模块化设计后,新功能开发周期缩短 40%,代码复用率提升至 65% * 遵循 "高内聚、低耦合" 原则,每个功能模块既保持独立演进,又通过统一接口规范实现协同工作 * 将重复的业务逻辑提取为通用方法或封装成工具类,避免代码冗余[(41)](https://wenku.csdn.net/answer/10jz8y629q) **Kotlin 带来的代码精简优势**显著[(41)](https://wenku.csdn.net/answer/10jz8y629q): Kotlin 提供了更简洁的语法,例如: * **数据类(data class)**:自动生成 equals、hashCode、toString 等方法 * **扩展函数**:无需继承即可为现有类添加功能 * **lambda 表达式**:简化集合操作和回调处理 * **空安全特性**:减少空指针检查代码 这些特性能够显著减少样板代码,在某些情况下可减少高达 30-40% 的代码量。 ### 1.4 代码优化工具与技术进展 **2025 年最新的代码优化工具和技术**呈现出智能化、自动化的发展趋势: 1. **Android Studio 的 AI 辅助功能**[(76)](https://www.showapi.com/news/article/68a2c47e4ddd79d135002f64): * AI 辅助编码:基于上下文智能补全代码,减少重复劳动 * 实时预览:无需频繁运行应用即可查看界面变化 * Gemini 功能:包括 rename(基于上下文为变量、类或方法建议合适名称)和 rethink(分析整个文件并建议新的变量和方法名称) 1. **新一代 Android Quantum Compiler (AQC)**[(71)](https://blog.csdn.net/qq_35905005/article/details/145770592): * 动态二进制翻译:根据设备硬件特性实时生成最优机器码 * 跨语言联合编译:Kotlin/Java/Rust 代码统一编译为 WASM-IR 中间层,提升执行效率 1. **构建速度优化**: * R8 支持多线程处理和增量构建,大幅提升构建速度[(85)](https://wenku.csdn.net/column/75uzw2ce6c) * 并行处理能力使大型项目的构建时间从 43 分钟缩短至 10 分钟以内 1. **代码分析工具**[(54)](https://pub.dev/packages/dead_code_analyzer/versions/1.1.7): * **dead\_code\_analyzer**:用于 Dart 和 Flutter 项目,识别未使用的代码元素(类、函数、变量) * **AndroidJunkCode**:专门分析 Android 项目中的垃圾代码,快速识别不再使用的代码、重复代码 * **UCDetector**:Eclipse 插件,用于检测不必要的代码 * **Android Lint**:静态代码分析工具,检测代码质量问题和性能问题 ## 二、资源层面优化策略 ### 2.1 图片资源优化技术 图片资源通常占据 APK 体积的**60-80%**,是包体积优化的重中之重。2025 年,图片优化技术取得了重大突破,特别是**AVIF 格式**的广泛应用带来了革命性的压缩效果。 **新一代图像格式的优势对比**: | 格式 | 压缩率优势 | 支持透明度 | 动画支持 | 最低 Android 版本 | 浏览器支持度 | | ---- | ------------------------------- | ----- | ---- | ------------- | ------- | | AVIF | 比 JPEG 小 40-90%,比 WebP 小 30-50% | ✓ | ✓ | 12 (API 31) | 93.44% | | WebP | 比 JPEG/PNG 小 25-35% | ✓ | ✓ | 4.0 (API 14) | 接近 100% | | JPEG | 基准 | ✗ | ✗ | 1.0 | 100% | | PNG | 基准 | ✓ | ✓ | 1.0 | 100% | **AVIF 格式的技术优势**极为显著[(93)](https://blog.csdn.net/2503_92849275/article/details/149858365): * 基于 AV1 视频编码技术,压缩率远超传统格式 * 支持 8 位、10 位、12 位色彩深度,提供更丰富的色彩表现 * 支持高动态范围(HDR)成像,能够呈现更广泛的色彩范围和更细腻的亮度变化 * 同时支持无损和有损压缩模式 * 对透明度的处理更加细腻,压缩比更高 **WebP 格式的成熟应用**已经得到广泛验证[(94)](https://developer.android.google.cn/studio/write/convert-webp?hl=pt): * 静态 WebP 支持 Android 4.0+,动态 WebP 支持 Android 9.0+ * 无损压缩比 PNG 小 25-34%,有损压缩比 JPEG 小 25-34% * 支持透明度和动画,是 GIF 动画的理想替代品 * 编码解码速度快,对设备性能要求较低 **图片压缩工具的选择与使用**: 1. **TinyPNG**[(109)](https://a1.art/zh/blog/best-image-compressor.html): * 支持 WebP、PNG、JPEG 格式 * 智能有损压缩,通过减少颜色数量实现压缩 * 免费版限制:每次最多 20 张,每张最大 5MB * 压缩效果:PNG 可压缩 50% 以上,几乎不影响视觉质量 1. **Google 官方工具**: * Android Studio 内置 WebP 转换功能 * 支持批量转换,可设置压缩质量参数 1. **命令行工具**: ``` \# 批量转换res/drawable目录下的PNG到WebP find . -name "\*.png" | xargs -I {} cwebp -q 80 {} -o {}.webp ``` **分辨率适配与资源管理策略**: Android 支持为不同屏幕密度提供适配资源[(103)](https://blog.51cto.com/u_16175475/13416051): * **drawable-ldpi** (120dpi):低密度屏幕 * **drawable-mdpi** (160dpi):中密度屏幕(基准) * **drawable-hdpi** (240dpi):高密度屏幕 * **drawable-xhdpi** (320dpi):超高密度屏幕 * **drawable-xxhdpi** (480dpi):超超高密度屏幕 * **drawable-xxxhdpi** (640dpi):超超超高密度屏幕 **资源匹配优先级规则**[(107)](https://wenku.csdn.net/column/2sgd5yvg8s): 1. 系统优先加载与设备 DPI 最匹配的资源目录 2. 若没有对应目录,系统会尝试加载更高 DPI 的资源(向上兼容) 3. 最终会使用默认的 drawable 目录资源 为了减少 APK 体积,可以采用以下策略: * 只提供必要的密度资源(如 mdpi、xhdpi、xxhdpi) * 使用矢量图(VectorDrawable)替代位图,避免为每个密度提供不同图片 * 对于不常用的图片,采用动态下载方式 ### 2.2 资源文件精简与检测 **无用资源的自动检测与清理**是资源优化的基础工作: 1. **Android Studio 内置工具**[(118)](https://wenku.csdn.net/answer/6viahxr6qz): * **Lint 工具**:通过 Analyze > Inspect Code 菜单运行,专门检测未使用的 drawable、layout、mipmap、values 资源 * **Android Resource Remover 插件**:可检测并移除未使用的资源 1. **第三方检测工具**: * **SDMaid**[(120)](https://www.downkuai.com/android/123281.html):专业的 Android 存储清理工具,可扫描设备并过滤不需要的文件目录 * **清浊**[(115)](https://sj.qq.com/topic/200074643):支持一键清理、应用通用清理、卸载残留清理、APK 清理等功能 * **Avast Cleanup**[(117)](https://m.romzhijia.net/app/AvastCleanupsjql_364236.html):智能识别并处理各类占用资源的冗余内容 1. **Gradle 配置优化**: 通过 resConfigs 属性指定应用支持的语言,减少不必要的本地化资源: ``` android { &#x20; defaultConfig { &#x20; resConfigs "en", "zh-rCN" // 只包含英文和简体中文 &#x20; } } ``` **资源复用与动态加载策略**: 1. **矢量图(VectorDrawable)的优势**[(122)](https://developer.android.com/develop/ui/views/graphics/vector-drawable-resources?hl=ID): * 基于 XML 定义的矢量图形,可无限缩放而不失真 * 同一文件可适配不同屏幕密度,大幅减少资源文件数量 * 文件体积小,特别适合图标等简单图形 * Android 5.0 (API 21) 开始原生支持,低版本可通过 AppCompat 库支持 1. **NinePatch 图片优化**: * 用于需要拉伸的图片(如按钮背景) * 只定义拉伸区域,避免图片变形 * 可显著减少图片资源数量 1. **资源动态加载**: * 将不常用的资源(如广告图片、用户头像)改为网络加载 * 使用 AssetManager 加载 assets 目录下的压缩资源 * 实现资源的按需加载,减少初始包体积 ### 2.3 音视频资源优化 音视频资源是应用体积的另一个重要组成部分,特别是在视频类、直播类应用中,音视频资源可能占据**70% 以上**的包体积。 **编解码技术的最新进展**: 1. **Android 16 的媒体播放优化**[(131)](https://www.nxrte.com/jishu/57259.html): * 使用 Rust 语言重写媒体编解码器,提高效率和安全性 * 减少解码视频或音频所需的进程数量 * 提升媒体播放的整体效率 1. **硬编解码优化**[(133)](https://juejin.cn/post/7472956559176007690): * 通过 SetSmartPlayerVideoHWDecoder 接口检测并启用 H.264/H.265 硬解码 * 根据设备支持情况自动选择硬解码或软解码 * 可降低 CPU 占用率 50% 以上,提升解码效率 1. **FFmpeg 优化策略**[(130)](https://wenku.csdn.net/column/2vijasy002): * 异步解码:避免阻塞主线程 * 零拷贝传输:减少内存复制开销 * NEON 指令加速:利用 ARM 架构的 SIMD 指令集 * 选择合适的比特率:在保证画质的前提下优化文件大小 **流媒体协议的选择与优化**: | 协议 | 优势 | 劣势 | 起播时延 | 适用场景 | | ----------- | ---------- | --------- | ---- | ------ | | HLS | 广泛支持,成熟稳定 | 起播慢,6-9 秒 | 中 | 直播、VOD | | DASH | 功能丰富,低延迟支持 | 服务器复杂度高 | 中 | 高质量流媒体 | | Progressive | 简单快速 | 无自适应能力 | 快 | 简单点播 | **HLS/DASH 低延迟优化配置**[(136)](https://juejin.cn/post/7545700885981446184): 1. **服务端配置**: * 分片时长:建议 2-6 秒,LL-HLS 使用 PART 分片可低至 0.21 秒 * 关键帧间隔(GOP):1 秒左右 * 首分片尽量小:约 1 秒的内容 1. **客户端配置**(Media3): ``` val liveCfg = MediaItem.LiveConfiguration.Builder() &#x20; .setMaxPlaybackSpeed(1.02f) // 轻微追赶机制 &#x20; .setTargetOffsetMs(3000) // 目标延迟3秒 &#x20; .setMinOffsetMs(2000) // 延迟下限2秒 &#x20; .setMaxOffsetMs(5000) // 延迟上限5秒 &#x20; .build() val item = MediaItem.Builder() &#x20; .setUri(uri) &#x20; .setLiveConfiguration(liveCfg) // 直播/低延迟配置 &#x20; .build() ``` 1. **ExoPlayer 网络栈优化**[(137)](https://blog.csdn.net/gitblog_01019/article/details/151330193): 使用 Cronet 作为网络引擎,通过 QUIC 协议和预加载等特性,能显著提升流媒体加载速度。 **音视频缓存策略**: 1. **MediaLoader 缓存方案**[(143)](https://wenku.csdn.net/doc/3a27ct85fx): * 支持在播放时同步缓存视频 / 音频内容 * 避免重复下载,减少数据消耗 * 可设置缓存大小和过期策略 1. **ExoPlayer 缓存机制**[(148)](https://blog.51cto.com/u_16213419/12610747): * 支持将流媒体内容缓存到本地存储 * 可配置缓存路径和大小 * 支持离线播放已缓存内容 1. **云端 vs 本地存储策略**[(145)](https://wenku.csdn.net/column/3qohtuuosj): * 核心音频(如提示音、背景音乐):打包在 APK 中 * 大体积音频(如音乐、语音):云端存储,按需下载 * 视频内容:全部采用云端存储,本地只缓存临时文件 ### 2.4 本地化资源优化 本地化资源往往被忽视,但对于多语言应用来说,这部分可能占据 \*\*15-25%\*\* 的包体积。 **多语言资源的按需打包**: 1. **resConfigs 精确配置**[(150)](https://developer.android.com/guide/topics/resources/multilingual-support?authuser=1\&hl=ja): 通过 resConfigs 属性明确指定应用支持的语言,Gradle 会自动排除不支持的语言资源: ``` android { &#x20; defaultConfig { &#x20; // 只包含英文、简体中文和繁体中文 &#x20; resConfigs "en", "zh-rCN", "zh-rTW" &#x20; } } ``` 1. **语言资源合并策略**[(155)](https://developer.android.com/guide/topics/resources/multilingual-support?authuser=4): 将不同地区的语言资源合并到最通用的父方言中,例如将 "zh-rCN" 和 "zh-rTW" 的共同资源放在 "zh" 目录下,只在各自目录中放置有差异的资源。 2. **动态语言切换**: 使用插件化或云端按需下载的方式加载语言资源,初始包只包含默认语言。 **Android App Bundle 的本地化优化**[(162)](https://www.droidcon.com/2025/08/12/this-one-build-setting-shrunk-my-apk-by-40-and-i-almost-missed-it-%F0%9F%A4%AF/): 如果使用 Android App Bundle(Google Play 要求 2021 年 8 月后所有新应用必须使用),Google Play 会自动根据用户设备语言分发相应的资源,无需额外配置 resConfigs 也能实现语言资源的优化。 **资源拆分与动态加载技术**: 1. **动态功能模块(Dynamic Feature)**[(151)](https://juejin.cn/post/7523041906269700111): * 将非核心功能(如 AR、支付、音视频模块)设置为动态功能 * 用户按需下载,减少初始包体积 * 可节省 20-40% 的下载体积 1. **Split APK 技术**[(164)](https://developer.android.com/build/configure-apk-splits?authuser=1\&hl=es): * 按屏幕密度生成不同 APK: ``` android { &#x20; splits { &#x20; density { &#x20; enable true &#x20; // 只生成mdpi、hdpi、xhdpi三种密度的APK &#x20; include "mdpi", "hdpi", "xhdpi" &#x20; // 排除xxxhdpi等高密度 &#x20; exclude "xxxhdpi" &#x20; } &#x20; } } ``` * 按 CPU 架构拆分: ``` android { &#x20; splits { &#x20; abi { &#x20; enable true &#x20; // 只包含arm64-v8a和armeabi-v7a &#x20; include "arm64-v8a", "armeabi-v7a" &#x20; // 排除x86等架构 &#x20; exclude "x86", "x86\_64" &#x20; } &#x20; } } ``` 1. **插件化资源管理**[(170)](https://juejin.cn/post/7514682489325305894): * 将应用功能拆分成独立插件 * 主应用只包含核心功能和资源 * 插件在运行时按需加载 * 可实现资源的动态更新和按需下载 ## 三、依赖库优化策略 依赖库往往是 APK 体积膨胀的主要原因之一,特别是当引入大型框架或包含大量传递依赖时。根据统计,第三方依赖库可能占据 APK 体积的**30-50%**。 ### 3.1 依赖分析工具的使用 **专业依赖分析工具**为优化提供了强大支撑: 1. **LibChecker**[(171)](https://juejin.cn/post/7546977677473103899): * 专业的 Android 应用架构分析工具 * 能够深入了解应用的内部结构和依赖关系 * 标记第三方库组件,帮助快速识别应用中使用的知名库 * 提供全面的依赖分析报告 1. **Dependency Analysis Gradle Plugin (DAGP)**[(173)](https://plugins.gradle.org/plugin/com.autonomousapps.dependency-analysis/2.15.0): ``` plugins { &#x20; id "com.autonomousapps.dependency-analysis" version "2.15.0" } ``` * 采用先进的字节码分析技术查找未使用的依赖项 * 识别应该直接声明的传递性依赖 * 检查配置是否正确(api、implementation、compileOnly 等) * 提供构建健康评估功能 1. **Gradle 内置依赖分析**[(176)](https://blog.51cto.com/u_16213341/13220424): * 使用命令行查看依赖树: ``` ./gradlew app:dependencies ``` * 查看 Android 特定依赖: ``` ./gradlew app:androidDependencies ``` * 生成详细的依赖报告: ``` ./gradlew --scan ``` 1. **Android Studio 可视化工具**[(176)](https://blog.51cto.com/u_16213341/13220424): * 通过 View > Tool Windows > Gradle 打开 Gradle 窗口 * 右键单击模块,选择 "Analyze Dependencies" * 以图形化方式展示依赖关系 ### 3.2 轻量级替代方案调研 **主流库的体积对比与替代方案**: | 功能 | 传统库 | 体积 | 轻量级替代 | 体积 | 节省比例 | 注意事项 | | ------- | -------- | ----- | ---------------- | ------ | ---- | -------------- | | JSON 解析 | Gson | 475KB | Moshi | 215KB | 55% | 需手动编写 JSON 适配器 | | 网络请求 | Retrofit | 650KB | OkHttp | 280KB | 57% | 需自行处理请求 / 响应 | | 图片加载 | Glide | 1.2MB | Picasso | 350KB | 71% | 功能相对简单 | | DI 框架 | Dagger2 | 1.4MB | Hilt | 900KB | 36% | 需要 AndroidX 支持 | | 数据库 | Room | 850KB | SQLiteOpenHelper | <100KB | >88% | 需手动处理 SQL | **具体替代方案详解**: 1. **JSON 解析库对比**: * **Gson**:功能全面,支持复杂对象映射,但体积较大(475KB) * **Moshi**:体积更小(215KB),性能略优,但需要手动编写 JSON 适配器 * **替代建议**:如果项目中的 JSON 结构相对简单且稳定,Moshi 是更好的选择 1. **网络请求库优化**: * **Retrofit + OkHttp**:完整的网络请求解决方案,但体积较大(Retrofit 650KB + OkHttp 280KB = 930KB) * **仅使用 OkHttp**:如果只需要基本的网络请求功能,直接使用 OkHttp 可节省 650KB * **优化策略**:分析项目中 Retrofit 的使用场景,仅在需要 RESTful API 时使用,其他场景用 OkHttp 替代 1. **图片加载库选择**: * **Glide**:功能强大,支持多种格式和动画,但体积达 1.2MB * **Picasso**:体积仅 350KB,适合简单的图片加载需求 * **优化建议**:根据项目需求选择,如果只需要基本的图片加载和缓存功能,Picasso 是更轻量的选择 1. **数据库解决方案**: * **Room**:Google 推荐的 ORM 框架,体积 850KB,提供了很多便利功能 * **原生 SQLite**:直接使用 SQLiteOpenHelper,体积小于 100KB * **选择策略**:对于简单的数据库操作,原生 SQLite 可以节省 750KB 以上;对于复杂查询,Room 的便利性值得其体积开销 ### 3.3 依赖冲突处理与版本管理 **依赖冲突的识别与解决**: 1. **冲突类型分析**[(187)](https://ask.csdn.net/questions/8818363): * 同一库的不同版本冲突(如 androidx.core:core-ktx:1.8.0 与 1.12.0) * 重复的类文件("Program type already present" 错误) * 传递依赖引入的不兼容版本 1. **冲突解决方法**: * **Gradle 排除依赖**[(190)](https://blog.51cto.com/u_16213462/12959068): ``` implementation('com.example.library:library:1.0.0') { &#x20; exclude group: 'com.android.support', module: 'support-v4' } ``` * **强制指定版本**: ``` configurations.all { &#x20; resolutionStrategy { &#x20; force 'com.android.support:support-v4:28.0.0' &#x20; } } ``` * **使用 Gradle --scan 分析**[(188)](https://blog.csdn.net/shejizuopin/article/details/148398435): ``` ./gradlew --scan ``` 1. **版本管理最佳实践**: * 使用统一的版本管理文件(如 versions.gradle) * 定期更新依赖库到最新稳定版本 * 避免使用 alpha/beta 版本 * 建立依赖库准入机制,评估每个新库的必要性 ### 3.4 自研 vs 集成的决策框架 **自研与集成的权衡分析**: 1. **适合自研的场景**: * 功能简单且项目有特殊需求 * 第三方库体积过大(>500KB)且只使用了小部分功能 * 需要高度定制化的功能 * 性能要求极高的核心功能 1. **适合集成的场景**: * 功能复杂且维护成本高 * 已有成熟稳定的开源库 * 需要跨平台兼容性 * 开发时间紧张 1. **决策评估模型**: | 评估维度 | 权重 | 自研得分 | 集成得分 | 加权得分 | | ------ | ---- | -------- | -------- | ----------------- | | 开发成本 | 30% | 8(高) | 2(低) | 自研: 2.4 集成: 0.6 | | 维护成本 | 25% | 7(高) | 3(低) | 自研: 1.75 集成: 0.75 | | 体积影响 | 20% | 9(低) | 3(高) | 自研: 1.8 集成: 0.6 | | 稳定性 | 15% | 4(低) | 8(高) | 自研: 0.6 集成: 1.2 | | 功能完整性 | 10% | 6(中等) | 9(高) | 自研: 0.6 集成: 0.9 | | **总分** | 100% | **7.15** | **4.05** | - | **实际案例分析**: 1. **网络请求模块**: * 第三方库:Retrofit + OkHttp(约 930KB) * 自研方案:基于 OkHttp 封装(约 200KB) * 节省:730KB(78%) * 建议:如果项目只需要基本的 GET/POST 请求,推荐自研 1. **图片加载模块**: * 第三方库:Glide(1.2MB) * 自研方案:基于 Android 原生 API + 简单缓存(约 100KB) * 节省:1.1MB(92%) * 建议:对于简单图片展示需求,可考虑自研 1. **JSON 解析模块**: * 第三方库:Gson(475KB) * 替代方案:Moshi(215KB) * 节省:260KB(55%) * 建议:优先使用轻量级的 Moshi 而非自研 ## 四、系统兼容性与性能适配 不同 Android 版本和设备性能对包体积优化策略的选择有重要影响。了解这些差异,才能制定出既有效又兼容的优化方案。 ### 4.1 不同 Android 版本的优化策略差异 **各版本的优化特性支持情况**: | Android 版本 | 发布时间 | 关键优化特性 | 影响 | | ------------ | ------ | ------------------------------ | -------------- | | 4.0 (API 14) | 2011 年 | WebP 静态图片支持 | 可开始使用 WebP 格式 | | 4.3 (API 18) | 2013 年 | WebP 透明图片支持 | 完整的 WebP 支持 | | 5.0 (API 21) | 2014 年 | VectorDrawable、Material Design | 矢量图支持,大幅减少图片资源 | | 7.0 (API 24) | 2016 年 | 多窗口模式、V2 签名 | 更安全的签名方式 | | 8.0 (API 26) | 2017 年 | 自动资源管理 | 系统自动管理应用资源 | | 9.0 (API 28) | 2018 年 | WebP 动画支持 | 完整的 WebP 动画支持 | | 12 (API 31) | 2021 年 | AVIF 支持、App Hint | 新一代图像格式 | | 16 (API TBD) | 2025 年 | Rust 编解码器、媒体优化 | 更高效的编解码 | **针对不同版本的优化策略**: 1. **Android 5.0+ (API 21+)**: * 全面使用 VectorDrawable 替代位图图标 * 使用 Android 5.0 + 特有的动画和过渡效果 * 利用系统的自动资源管理功能 1. **Android 8.0+ (API 26+)**: * 启用自动资源管理,系统会根据设备特性自动选择合适的资源 * 使用 Adaptive Icons 功能 * 利用后台限制优化应用行为 1. **Android 12+ (API 31+)**: * 全面使用 AVIF 格式图片 * 利用 App Hint 功能优化应用启动 * 使用新的媒体编解码器提升音视频性能 1. **兼容低版本的策略**: * 使用 AppCompat 库提供向后兼容 * 为不同版本提供差异化的资源 * 使用 ProGuard/R8 的兼容性模式 ### 4.2 设备性能差异对优化的影响 设备性能直接影响优化策略的选择,特别是在使用高级特性时。 **高端设备(旗舰级)的优化策略**: * 可使用更复杂的动画和过渡效果 * 支持更高分辨率的图片和视频 * 可使用 GPU 加速的渲染技术 * 推荐使用 AVIF 等高压缩率格式 **中端设备(主流级)的优化策略**: * 平衡功能和性能,避免过度优化 * 使用 WebP 格式替代传统图片 * 适当降低动画复杂度 * 采用智能加载策略,只加载可见区域内容 **低端设备(入门级)的优化策略**: * 禁用大部分动画效果 * 使用最低分辨率的必要图片 * 避免使用复杂的渲染技术 * 优先使用静态资源,减少动态计算 **设备性能检测与适配代码示例**: ``` // 检测设备是否支持高级特性 fun isHighEndDevice(context: Context): Boolean { &#x20; val packageManager = context.packageManager &#x20; val features = packageManager.systemAvailableFeatures &#x20; &#x20; &#x20; // 检查是否支持OpenGL ES 3.0及以上 &#x20; val hasGles3 = features.any { it.name == "android.hardware.graphics.gles3" } &#x20; &#x20; &#x20; // 检查内存大小(以MB为单位) &#x20; val memoryInfo = ActivityManager.MemoryInfo() &#x20; val activityManager = context.getSystemService(Context.ACTIVITY\_SERVICE) as ActivityManager &#x20; activityManager.getMemoryInfo(memoryInfo) &#x20; val totalMem = memoryInfo.totalMem / 1024 / 1024 &#x20; &#x20; &#x20; return hasGles3 && totalMem >= 3072 // 3GB及以上内存 } // 根据设备性能选择图片质量 fun getImageQuality(deviceLevel: String): Int { &#x20; return when (deviceLevel) { &#x20; "high\_end" -> 80 // 高质量 &#x20; "medium" -> 60 // 中等质量 &#x20; else -> 40 // 低质量 &#x20; } } ``` ### 4.3 应用瘦身技术的系统支持 **Android App Bundle 的系统支持**: Android App Bundle 是 Google 推荐的应用分发格式,它提供了多项系统级的优化支持: 1. **资源精准分发**: * Google Play 自动根据设备特性(语言、屏幕密度、CPU 架构)生成定制化 APK * 平均减少 47% 的下载体积 * 支持按模块分发,用户只下载需要的功能 1. **动态功能模块**: * 非核心功能可以按需下载 * 支持条件分发(如仅高端设备下载 AR 功能) * 支持即时应用(Instant Apps) 1. **Asset Delivery**: * 专门用于游戏资源的分发 * 支持纹理包、音频包等的按需加载 * 提供下载进度监控和断点续传 **Split APK 的系统支持**: 虽然 Android App Bundle 是推荐方案,但 Split APK 在某些场景下仍有用武之地[(164)](https://developer.android.com/build/configure-apk-splits?authuser=1\&hl=es): 1. **按屏幕密度拆分**: ``` android { &#x20; splits { &#x20; density { &#x20; enable true &#x20; // 生成不同密度的APK &#x20; include "mdpi", "hdpi", "xhdpi", "xxhdpi" &#x20; // 每个APK只包含对应密度的资源 &#x20; } &#x20; } } ``` 1. **按 CPU 架构拆分**: ``` android { &#x20; splits { &#x20; abi { &#x20; enable true &#x20; include "arm64-v8a", "armeabi-v7a" &#x20; exclude "x86", "x86\_64" &#x20; } &#x20; } } ``` 1. **按语言拆分**(仅 Instant Apps 支持): ``` android { &#x20; splits { &#x20; language { &#x20; enable true &#x20; include "en", "zh" &#x20; } &#x20; } } ``` **BuildConfig 的条件编译支持**: 利用 BuildConfig 进行条件编译,可以在不同版本中包含不同的代码和资源: ``` android { &#x20; buildTypes { &#x20; release { &#x20; buildConfigField "boolean", "ENABLE\_ADVANCED\_FEATURES", "false" &#x20; } &#x20; premium { &#x20; buildConfigField "boolean", "ENABLE\_ADVANCED\_FEATURES", "true" &#x20; } &#x20; } } ``` 在代码中使用: ``` if (BuildConfig.ENABLE\_ADVANCED\_FEATURES) { &#x20; // 包含高级功能的代码 } else { &#x20; // 基础功能代码 } ``` ### 4.4 兼容性测试与验证 确保优化后的应用在不同设备和系统版本上正常运行至关重要。 **兼容性测试策略**: 1. **模拟器测试矩阵**: * 覆盖 API 19 到最新版本 * 包含不同屏幕尺寸和密度 * 包含不同 CPU 架构(arm、x86) * 测试低端、中端、高端设备配置 1. **真实设备测试**: * 至少包含 5-10 台不同品牌和型号的设备 * 覆盖主要厂商(三星、小米、OPPO、vivo 等) * 包含不同 Android 版本 1. **自动化测试**: * 使用 Espresso 进行 UI 测试 * 使用 JUnit 进行单元测试 * 使用 Robolectric 进行 Android 环境模拟测试 1. **内存和性能监控**: * 使用 Android Profiler 监控内存使用 * 使用 Systrace 分析性能瓶颈 * 使用 StrictMode 检测性能问题 **常见兼容性问题及解决方案**: 1. **资源找不到问题**: * 原因:不同版本的资源 ID 可能不同 * 解决方案:使用 ContextCompat.getColor () 等兼容方法 1. **方法找不到异常**: * 原因:使用了高版本 API 但未做版本检查 * 解决方案:使用 Build.VERSION.SDK\_INT 进行版本判断 1. **图片显示异常**: * 原因:低版本不支持新的图片格式 * 解决方案:为不同版本提供不同格式的图片 1. **动画效果异常**: * 原因:某些动画 API 在低版本中不存在 * 解决方案:使用兼容库或提供降级方案 ## 五、综合评估与实施策略 ### 5.1 包体积监控体系建设 建立完善的包体积监控体系是持续优化的基础。 **监控工具的选择与使用**: 1. **Android Studio 内置工具**: * **APK Analyzer**:通过 Build > Analyze APK 打开,提供详细的包内容分析 * **Profiler**:实时监控应用内存和 CPU 使用 * **Lint**:检测代码和资源问题 1. **Gradle 插件监控**: ``` // 在build.gradle中添加体积监控 task printApkSize(type: Exec) { &#x20; commandLine 'du', '-sh', 'app/build/outputs/apk/release/app-release.apk' } ``` 1. **第三方监控工具**: ``` \# 使用Bundletool分析AAB包体积 bundletool get-size total --bundle=app-release.aab --dimensions="ABI,SCREEN\_DENSITY,LOCALE" ``` * **apkanalyzer**:Google 官方的 APK 分析工具 * **Bundletool**:用于分析 Android App Bundle 的工具 **监控指标体系**: | 指标类别 | 具体指标 | 监控频率 | 目标值 | | ---- | ---------- | ---- | ------------------- | | 总体积 | APK/AAB 大小 | 每次构建 | <50MB(国内)<100MB(海外) | | 代码体积 | DEX 大小 | 每次构建 | <30MB | | 资源体积 | 图片、音频、视频 | 每次构建 | <20MB | | 依赖体积 | 第三方库总和 | 每周 | <15MB | | 增量监控 | 版本间变化 | 每次发布 | <5% 增长 | **自动化监控流程**: 1. **CI/CD 集成**: * 在 Jenkins 或 GitHub Actions 中集成包体积检查 * 设置体积增长阈值,超过时报警 * 生成体积变化趋势报告 1. **定期审计**: * 每周生成依赖库使用报告 * 每月进行一次全面的体积分析 * 每季度评估优化效果 ### 5.2 分阶段优化实施计划 制定合理的优化计划,逐步实施各项措施。 **第一阶段:基础优化(1-2 周)** 重点任务: * 启用 R8 压缩和混淆 * 配置 resConfigs 减少语言资源 * 使用 VectorDrawable 替代简单图标 * 删除明显的无用资源 预期效果:减少 15-25% 的包体积 实施步骤: 1. 在 build.gradle 中启用 R8 和资源压缩 2. 使用 Lint 扫描并清理无用资源 3. 手动检查并删除未使用的代码和资源 4. 转换所有简单图标为 VectorDrawable **第二阶段:深度优化(3-4 周)** 重点任务: * 分析依赖树,移除冗余依赖 * 转换图片格式(WebP/AVIF) * 优化音视频资源 * 实现动态功能模块 预期效果:再减少 20-30% 的包体积 实施步骤: 1. 使用依赖分析工具识别冗余库 2. 批量转换图片资源格式 3. 将大体积音视频改为网络加载 4. 将非核心功能模块化 **第三阶段:极致优化(5-6 周)** 重点任务: * 自研轻量级替代方案 * 实施高级资源拆分 * 优化本地存储策略 * 全面测试兼容性 预期效果:再减少 10-15% 的包体积 实施步骤: 1. 评估并替换体积过大的第三方库 2. 实现 Android App Bundle 或 Split APK 3. 优化数据库和文件存储 4. 进行全面的兼容性测试 **优化效果跟踪表**: | 优化措施 | 实施前体积 | 实施后体积 | 减少量 | 减少比例 | | ------ | ------- | ----------- | ----------- | ---------- | | 基础优化 | 100MB | 75-85MB | 15-25MB | 15-25% | | 深度优化 | 75-85MB | 50-65MB | 25-30MB | 20-30% | | 极致优化 | 50-65MB | 40-55MB | 10-15MB | 10-15% | | **总计** | 100MB | **40-55MB** | **45-60MB** | **45-60%** | ### 5.3 效果评估与风险控制 科学评估优化效果,并做好风险控制。 **效果评估方法**: 1. **定量评估指标**: * 包体积减少比例 * 下载转化率提升 * 安装成功率变化 * 启动时间变化 * 内存使用量变化 1. **定性评估指标**: * 用户满意度调查 * 应用评分变化 * 卸载率变化 * 功能完整性验证 1. **A/B 测试方法**: * 将优化后的版本与原版本进行对比测试 * 选择部分用户群体进行试点 * 收集各项性能指标和用户反馈 **风险控制策略**: 1. **功能风险控制**: * 建立完善的单元测试和集成测试 * 使用版本控制系统,便于回滚 * 分阶段发布,逐步扩大影响范围 1. **性能风险控制**: * 监控应用崩溃率变化 * 跟踪内存泄漏问题 * 测试不同设备上的性能表现 1. **兼容性风险控制**: * 覆盖所有目标 Android 版本测试 * 测试主流设备品牌和型号 * 准备降级方案 1. **回滚机制**: * 保留上一版本的完整代码和资源 * 建立快速发布通道 * 制定详细的回滚流程 **常见问题及应对方案**: 1. **优化后功能异常**: * 原因:混淆导致反射或序列化问题 * 解决方案:添加 keep 规则,保护关键类和方法 1. **图片显示异常**: * 原因:格式转换或压缩导致 * 解决方案:使用质量更高的压缩参数,或提供备用图片 1. **性能下降**: * 原因:过度优化导致计算量增加 * 解决方案:重新评估优化策略,在体积和性能间找到平衡 1. **包体积反弹**: * 原因:新增功能或依赖 * 解决方案:建立体积预算制度,新增功能必须有相应的优化补偿 ## 结语 通过本指南的全面分析,我们可以看到 Android 应用包体积优化是一个系统性工程,涉及代码、资源、依赖库等多个层面。通过采用最新的技术和工具,如 AGP 8.12.0 的革命性资源压缩优化、AVIF 图像格式、R8 深度优化等,**现代 Android 应用完全可以实现 45-60% 的体积缩减**。 关键成功因素包括: 1. **技术选择**:紧跟最新技术发展,选择合适的优化方案 2. **系统化实施**:制定分阶段计划,逐步推进各项优化措施 3. **持续监控**:建立完善的监控体系,及时发现和解决问题 4. **兼容性保障**:确保优化不影响功能和用户体验 特别值得强调的是,2025 年的技术进展为我们提供了前所未有的优化空间。从 AI 辅助编码到新一代编译器,从革命性的资源压缩到高效的编解码技术,这些创新正在重塑 Android 应用的开发和优化方式。 建议开发者在实施优化时,始终以用户体验为中心,在包体积、性能和功能之间找到最佳平衡点。通过科学的方法和持续的努力,相信每一个 Android 应用都能在保持强大功能的同时,拥有轻盈的身材,为用户带来更好的使用体验。 **参考资料&#x20;** \[1] Réduire, &#x20;obscurcir et optimiser votre application[ https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com](https://developer.android.com/build/shrink-code?hl=fr\&ref=content.kayssel.com) \[2] R8 FAQ[ https://r8.googlesource.com/r8/+/refs/heads/8.1/compatibility-faq.md](https://r8.googlesource.com/r8/+/refs/heads/8.1/compatibility-faq.md) \[3] Добавить глобальные параметры[ https://developer.android.com/topic/performance/app-optimization/global-options?hl=ru](https://developer.android.com/topic/performance/app-optimization/global-options?hl=ru) \[4] D8 dexer and R8 shrinker[ https://r8.googlesource.com/r8/+/master/README.md](https://r8.googlesource.com/r8/+/master/README.md) \[5] Proguard / R8 configuration #1198[ https://github.com/callstack/repack/issues/1198](https://github.com/callstack/repack/issues/1198) \[6] Optimizing Java Code[ https://chromium.googlesource.com/experimental/chromium/src/+/refs/tags/81.0.4026.1/build/android/docs/java\_optimization.md](https://chromium.googlesource.com/experimental/chromium/src/+/refs/tags/81.0.4026.1/build/android/docs/java_optimization.md) \[7] Enable app optimization[ https://developer.android.com/topic/performance/app-optimization/enable-app-optimization](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization) \[8] アプリの圧縮、難読化、最適化[ https://developer.android.com/build/shrink-code?hl=ja\&ref=content.kayssel.com](https://developer.android.com/build/shrink-code?hl=ja\&ref=content.kayssel.com) \[9] 代码混淆进阶革命:从ProGuard到R8,Doujin-moe-Android反编译防护的6大增强策略与压缩收益 - CSDN文库[ https://wenku.csdn.net/column/75uzw2ce6c](https://wenku.csdn.net/column/75uzw2ce6c) \[10] Google Brings Optimized Resource Shrinking in Latest Android Gradle Plugin[ https://www.infoq.com/news/2025/09/android-optimized-R8/](https://www.infoq.com/news/2025/09/android-optimized-R8/) \[11] Android 代码混淆 R8与Proguard\_r8混淆-CSDN博客[ https://blog.csdn.net/fitaotao/article/details/115083963](https://blog.csdn.net/fitaotao/article/details/115083963) \[12] 新Android插件上线,应用体积可减半,开发者必看!\_搜狐网[ https://m.sohu.com/a/938604042\_122004016/](https://m.sohu.com/a/938604042_122004016/) \[13] 深入理解R8混淆:保护、瘦身与优化Android应用Android混淆就像 \*\*“给代码戴上面具”\*\* —— 把类名、方 - 掘金[ https://juejin.cn/post/7473083144171700262](https://juejin.cn/post/7473083144171700262) \[14] Kotlin代码混淆与压缩技巧详解在 Android 开发中,ProGuard 和 R8 是用于代码压缩(Shrinki - 掘金[ https://juejin.cn/post/7502457440441925683](https://juejin.cn/post/7502457440441925683) \[15] 新版 Android 插件登场,应用能瘦身 50%,Google 把代码优化和资源压缩合二为一\_InfoQ[ http://m.toutiao.com/group/7553962015706972706/?upstream\_biz=doubao](http://m.toutiao.com/group/7553962015706972706/?upstream_biz=doubao) \[16] R8 Optimization: The Modern Android Code Shrinker[ https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker](https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker) \[17] Shrink, obfuscate, &#x20;and optimize your app[ https://developer.android.com/build/shrink-code?authuser=7](https://developer.android.com/build/shrink-code?authuser=7) \[18] Menyusutkan, meng-obfuscate, dan mengoptimalkan aplikasi Anda[ https://developer.android.com/build/shrink-code?hl=id\&source=post\_page-----692a3e72765d---------------------------------------](https://developer.android.com/build/shrink-code?hl=id\&source=post_page-----692a3e72765d---------------------------------------) \[19] R8 - The Next Evolution of Obfuscation for Enhanced Android Security[ https://moldstud.com/articles/p-r8-the-next-evolution-of-obfuscation-for-enhanced-android-security](https://moldstud.com/articles/p-r8-the-next-evolution-of-obfuscation-for-enhanced-android-security) \[20] Android R8-CSDN博客[ https://blog.csdn.net/steve\_xiaohai/article/details/131849139](https://blog.csdn.net/steve_xiaohai/article/details/131849139) \[21] Android官方推荐,使用R8来压缩您的应用-CSDN博客[ https://blog.csdn.net/c10WTiybQ1Ye3/article/details/115682781](https://blog.csdn.net/c10WTiybQ1Ye3/article/details/115682781) \[22] AndroidStudio-apk瘦身-CSDN博客[ https://blog.csdn.net/mcsbary/article/details/107359402](https://blog.csdn.net/mcsbary/article/details/107359402) \[23] Shrink, obfuscate, &#x20;and optimize your app[ https://developer.android.com/build/shrink-code?authuser=7](https://developer.android.com/build/shrink-code?authuser=7) \[24] R8 Optimization: The Modern Android Code Shrinker[ https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker](https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker) \[25] pr0gramm-app/app/proguard-rules-base.pro at master · pr0gramm-com/pr0gramm-app · GitHub[ https://github.com/pr0gramm-com/pr0gramm-app/blob/master/app/proguard-rules-base.pro](https://github.com/pr0gramm-com/pr0gramm-app/blob/master/app/proguard-rules-base.pro) \[26] Optimierungen schrittweise einführen[ https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=0000\&hl=de](https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=0000\&hl=de) \[27] Android 缩减、混淆处理和优化应用\_android.enabler8.fullmode-CSDN博客[ https://blog.csdn.net/qijingwang/article/details/134751787](https://blog.csdn.net/qijingwang/article/details/134751787) \[28] R8 Optimization: Value Assumption[ https://jakewharton.com/r8-optimization-value-assumption/](https://jakewharton.com/r8-optimization-value-assumption/) \[29] 奥迪R8 -懂车帝[ https://www.dongchedi.com/auto/series/91](https://www.dongchedi.com/auto/series/91) \[30] 启用应用程式最佳化功能 | App quality | Android Developers[ https://developer.android.com/topic/performance/app-optimization/enable-app-optimization?hl=zh-tw\&ref=content.kayssel.com](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization?hl=zh-tw\&ref=content.kayssel.com) \[31] アプリの圧縮、難読化、最適化[ https://developer.android.com/build/shrink-code?hl=ja\&source=post\_page-----692a3e72765d---------------------------------------](https://developer.android.com/build/shrink-code?hl=ja\&source=post_page-----692a3e72765d---------------------------------------) \[32] D8 dexer and R8 shrinker[ https://android.googlesource.com/platform/external/r8/+/master/README.md](https://android.googlesource.com/platform/external/r8/+/master/README.md) \[33] Внедряйте оптимизацию постепенно[ https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=9\&hl=ru](https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=9\&hl=ru) \[34] Menerapkan pengoptimalan secara bertahap[ https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=4\&hl=id](https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=4\&hl=id) \[35] 逐步采用优化措施 | App quality | Android Developers[ https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=09\&hl=zh-cn](https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally?authuser=09\&hl=zh-cn) \[36] Optimize Tree Shaking Configuration for Better Bundle Size #600[ https://github.com/bdougie/contributor.info/issues/600](https://github.com/bdougie/contributor.info/issues/600) \[37] Ativar a otimização do app[ https://developer.android.com/topic/performance/app-optimization/enable-app-optimization?authuser=3\&hl=pt](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization?authuser=3\&hl=pt) \[38] Android技术架构演进与未来\_mob64ca140ac564的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213660/14316059](https://blog.51cto.com/u_16213660/14316059) \[39] Kotlin重构Android项目实践以下是使用 Kotlin 重构 Android 项目的 5 个常见场景实践,通过对 - 掘金[ https://juejin.cn/post/7500405809429430284](https://juejin.cn/post/7500405809429430284) \[40] Android Guidelines 中的代码重构技巧:在不破坏功能的前提下改进代码质量-CSDN博客[ https://blog.csdn.net/gitblog\_00551/article/details/154564085](https://blog.csdn.net/gitblog_00551/article/details/154564085) \[41] android studio代码精简 - CSDN文库[ https://wenku.csdn.net/answer/10jz8y629q](https://wenku.csdn.net/answer/10jz8y629q) \[42] App verkleinern, &#x20;verschleiern und optimieren[ https://developer.android.com/build/shrink-code?hl=de\&ref=content.kayssel.com](https://developer.android.com/build/shrink-code?hl=de\&ref=content.kayssel.com) \[43] 앱 축소, 난독화 및 최적화[ https://developer.android.com/build/shrink-code?hl=ko\&ref=content.kayssel.com](https://developer.android.com/build/shrink-code?hl=ko\&ref=content.kayssel.com) \[44] Kotin代码优化与重构实践源码级分析(65)\_51CTO博客\_代码优化技术[ https://blog.51cto.com/u\_12472724/14136468](https://blog.51cto.com/u_12472724/14136468) \[45] 缩减应用大小 | Build for Billions | Android Developers[ https://dev.android.com/guide/topics/androidgo/optimize-size?hl=zh-cn](https://dev.android.com/guide/topics/androidgo/optimize-size?hl=zh-cn) \[46] Mengurangi ukuran aplikasi Anda[ https://developer.android.com/topic/performance/reduce-apk-size?hl=id\&trk=article-ssr-frontend-pulse\_little-text-block](https://developer.android.com/topic/performance/reduce-apk-size?hl=id\&trk=article-ssr-frontend-pulse_little-text-block) \[47] Reduzir, ofuscar e otimizar o app[ https://developer.android.com/build/shrink-code?hl=pt-br\&ref=content.kayssel.com](https://developer.android.com/build/shrink-code?hl=pt-br\&ref=content.kayssel.com) \[48] Reduce your app size[ https://developer.android.google.cn/topic/performance/reduce-apk-size.html](https://developer.android.google.cn/topic/performance/reduce-apk-size.html) \[49] Reduza o tamanho do seu app[ https://developer.android.com/topic/performance/reduce-apk-size?hl=pt](https://developer.android.com/topic/performance/reduce-apk-size?hl=pt) \[50] Reduce the size of your instant app[ https://developer.android.com/topic/google-play-instant/guides/reduce-module-size](https://developer.android.com/topic/google-play-instant/guides/reduce-module-size) \[51] Shrink, obfuscate, and optimize your app[ https://developer.android.com/build/shrink-code?authuser=3](https://developer.android.com/build/shrink-code?authuser=3) \[52] Android Studio中FindBugs插件的使用与代码质量提升\_51CTO学堂\_专业的IT技能学习平台[ https://edu.51cto.com/article/note/39630.html](https://edu.51cto.com/article/note/39630.html) \[53] Improve your code with lint checks[ https://developer.android.com/studio/write/lint?authuser=9](https://developer.android.com/studio/write/lint?authuser=9) \[54] dead\_code\_analyzer 1.1.7[ https://pub.dev/packages/dead\_code\_analyzer/versions/1.1.7](https://pub.dev/packages/dead_code_analyzer/versions/1.1.7) \[55] AndroidJunkCode 怎么使用的\_mob64ca12d3dbd9的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213314/12276334](https://blog.51cto.com/u_16213314/12276334) \[56] Android Studio 工具:Lint 代码扫描工具(含自定义lint)\_redundant call to 'format()-CSDN博客[ https://blog.csdn.net/jinpeng9001/article/details/82761360](https://blog.csdn.net/jinpeng9001/article/details/82761360) \[57] 删除Android工程中无用代码和资源\_android 工程多余代码文件及资源清理-CSDN博客[ https://blog.csdn.net/tanmy0527/article/details/46009171](https://blog.csdn.net/tanmy0527/article/details/46009171) \[58] Android lint是在ADT16提供的新工具,它是一个 - 野生鲫鱼 - 沸点 - 掘金 - 中文技术社区[ https://juejin.cn/pin/7055492576178077727](https://juejin.cn/pin/7055492576178077727) \[59] Android Gradle प्लग इन के DSL/API को माइग्रेट करने की टाइमलाइन[ https://developer.android.com/build/releases/gradle-plugin-roadmap?%3Bauthuser=5\&authuser=5\&hl=hi](https://developer.android.com/build/releases/gradle-plugin-roadmap?%3Bauthuser=5\&authuser=5\&hl=hi) \[60] المخطط الزمني لنقل بيانات مكوّنات Android Gradle Plugin أو واجهة برمجة التطبيقات:[ https://developer.android.com/build/releases/gradle-plugin-roadmap?hl=ar](https://developer.android.com/build/releases/gradle-plugin-roadmap?hl=ar) \[61] Android Gradle 插件预览版版本说明 | Android Studio | Android Developers[ https://developer.android.com/build/releases/agp-preview?authuser=7\&hl=zh-cn](https://developer.android.com/build/releases/agp-preview?authuser=7\&hl=zh-cn) \[62] לוח הזמנים להעברת ה-DSL/API של פלאגין Android Gradle[ https://developer.android.com/build/releases/gradle-plugin-roadmap?authuser=9\&hl=he](https://developer.android.com/build/releases/gradle-plugin-roadmap?authuser=9\&hl=he) \[63] Android Gradle Eklentisi DSL/API taşıma zaman çizelgesi[ https://developer.android.com/build/releases/gradle-plugin-roadmap?authuser=0000\&hl=tr](https://developer.android.com/build/releases/gradle-plugin-roadmap?authuser=0000\&hl=tr) \[64] Plug-in Android Gradle 8. 12\. 0 (juillet 2025)[ https://developer.android.com/build/releases/past-releases/agp-8-12-0-release-notes?hl=fr](https://developer.android.com/build/releases/past-releases/agp-8-12-0-release-notes?hl=fr) \[65] Плагин Android Gradle 8. 12. 0 (июль 2025 г.)[ https://developer.android.com/build/releases/past-releases/agp-8-12-0-release-notes?hl=ru](https://developer.android.com/build/releases/past-releases/agp-8-12-0-release-notes?hl=ru) \[66] Enable app optimization | App quality | Android Developers[ https://developer.android.com/build/enable-app-optimization](https://developer.android.com/build/enable-app-optimization) \[67] 新版 Android 插件登场,应用能瘦身 50%,Google 把代码优化和资源压缩合二为一\_InfoQ[ http://m.toutiao.com/group/7553962015706972706/?upstream\_biz=doubao](http://m.toutiao.com/group/7553962015706972706/?upstream_biz=doubao) \[68] Google Brings Optimized Resource Shrinking in Latest Android Gradle Plugin[ https://www.infoq.com/news/2025/09/android-optimized-R8/](https://www.infoq.com/news/2025/09/android-optimized-R8/) \[69] R8 Optimization: The Modern Android Code Shrinker[ https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker](https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker) \[70] 新版 Android 插件登场,应用能瘦身 50%,Google 把代码优化和资源压缩合二为一\_InfoQ[ http://m.toutiao.com/group/7553962015706972706/?upstream\_biz=doubao](http://m.toutiao.com/group/7553962015706972706/?upstream_biz=doubao) \[71] Android 2025年性能优化:技术趋势与实战策略\_perfgpt-CSDN博客[ https://blog.csdn.net/qq\_35905005/article/details/145770592](https://blog.csdn.net/qq_35905005/article/details/145770592) \[72] 18% Faster Compiles, 0% Compromises[ https://android-developers.googleblog.com/2025/12/18-faster-compiles-0-compromises.html?m=1](https://android-developers.googleblog.com/2025/12/18-faster-compiles-0-compromises.html?m=1) \[73] Android 宣布 Runtime 编译速度史诗级提升:在编译时间上优化了 18%\_ultra255编译android12需要多长时间-CSDN博客[ https://carguo.blog.csdn.net/article/details/155972979](https://carguo.blog.csdn.net/article/details/155972979) \[74] 新Android插件上线,应用体积可减半,开发者必看!\_搜狐网[ https://m.sohu.com/a/938604042\_122004016/](https://m.sohu.com/a/938604042_122004016/) \[75] Enable app optimization | App quality | Android Developers[ https://developer.android.com/build/enable-app-optimization](https://developer.android.com/build/enable-app-optimization) \[76] 智创飞跃:Android技术革新下的开发新篇章-易源AI资讯 | 万维易源[ https://www.showapi.com/news/article/68a2c47e4ddd79d135002f64](https://www.showapi.com/news/article/68a2c47e4ddd79d135002f64) \[77] Google Brings Optimized Resource Shrinking in Latest Android Gradle Plugin[ https://www.infoq.com/news/2025/09/android-optimized-R8/](https://www.infoq.com/news/2025/09/android-optimized-R8/) \[78] Android Studio Gets Smarter, Faster, and More Cross-Platform at Google I/O 2025[ https://mspoweruser.com/android-studio-gets-smarter-faster-and-more-cross-platform-at-google-i-o-2025/](https://mspoweruser.com/android-studio-gets-smarter-faster-and-more-cross-platform-at-google-i-o-2025/) \[79] How to Generate Production-ready Code in a Week Instead of a Month[ https://www.dhiwise.com/post/production-ready-android-app-code-in-week](https://www.dhiwise.com/post/production-ready-android-app-code-in-week) \[80] تحسين ألعاب Android[ https://developer.android.com/games/optimize/overview?authuser=8\&hl=ar](https://developer.android.com/games/optimize/overview?authuser=8\&hl=ar) \[81] Shrink, obfuscate, &#x20;and optimize your app[ https://developer.android.com/build/shrink-code?authuser=09](https://developer.android.com/build/shrink-code?authuser=09) \[82] Several new Gemini features available in latest Android Studio release[ https://sdtimes.com/mobile/several-new-gemini-features-available-in-latest-android-studio-release/](https://sdtimes.com/mobile/several-new-gemini-features-available-in-latest-android-studio-release/) \[83] Ativar a otimização do app[ https://developer.android.com/topic/performance/app-optimization/enable-app-optimization?hl=pt-br\&skip\_cache=true](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization?hl=pt-br\&skip_cache=true) \[84] Android高手笔记-D8, R8编译优化\_android.enabler8=false-CSDN博客[ https://blog.csdn.net/o118abcdef/article/details/122480050](https://blog.csdn.net/o118abcdef/article/details/122480050) \[85] 代码混淆进阶革命:从ProGuard到R8,Doujin-moe-Android反编译防护的6大增强策略与压缩收益 - CSDN文库[ https://wenku.csdn.net/column/75uzw2ce6c](https://wenku.csdn.net/column/75uzw2ce6c) \[86] ReaSoft Development Announces reaConverter 8 Release Candidate Now Available for Final Testing[ https://www.reasoft.com/about/press/reaconverter/may\_07\_2025.html](https://www.reasoft.com/about/press/reaconverter/may_07_2025.html) \[87] R8 Optimization: The Modern Android Code Shrinker[ https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker](https://peerlist.io/hpnightowl/articles/r8-optimization-the-modern-android-code-shrinker) \[88] R8DIUM Changelog[ https://github.com/sjstein/R8DIUM/blob/master/changelog.md](https://github.com/sjstein/R8DIUM/blob/master/changelog.md) \[89] 【Android 构建优化】R8 : 混淆,压缩与优化引言 你是否也到过自己的Android项目,在debug时项目是正 - 掘金[ https://juejin.cn/post/7549314246204473354](https://juejin.cn/post/7549314246204473354) \[90] Android 代码混淆 R8与Proguard\_r8混淆-CSDN博客[ https://blog.csdn.net/fitaotao/article/details/115083963](https://blog.csdn.net/fitaotao/article/details/115083963) \[91] 支持的媒体格式 | Android 媒体 | Android 开发者[ https://android-docs.cn/media/platform/supported-formats](https://android-docs.cn/media/platform/supported-formats) \[92] การลดขนาดการดาวน์โหลดภาพ[ https://developer.android.com/develop/ui/views/graphics/reduce-image-sizes?authuser=1\&hl=th](https://developer.android.com/develop/ui/views/graphics/reduce-image-sizes?authuser=1\&hl=th) \[93] 图像优化革命:AVIF 格式与 WebP 的终极对决\_avif vs webp-CSDN博客[ https://blog.csdn.net/2503\_92849275/article/details/149858365](https://blog.csdn.net/2503_92849275/article/details/149858365) \[94] Criar imagens WebP[ https://developer.android.google.cn/studio/write/convert-webp?hl=pt](https://developer.android.google.cn/studio/write/convert-webp?hl=pt) \[95] 数据万象 通过 Android 和 iOS 快速接入 AVIF[ https://cloud.tencent.com/document/practice/460/90095](https://cloud.tencent.com/document/practice/460/90095) \[96] 性能优化——Android图片压缩与优化的几种方式\_android jpg或png。对图片进行优化,一般是转换成svg,或者webp-CSDN博客[ https://blog.csdn.net/u013928412/article/details/80358597](https://blog.csdn.net/u013928412/article/details/80358597) \[97] 安卓图片性能优化技巧针对图片加载场景的进阶内存优化技巧,需结合图像格式选择、解码策略、内存复用机制、缓存架构及系统协作等 - 掘金[ https://juejin.cn/post/7540473266680381449](https://juejin.cn/post/7540473266680381449) \[98] Android Bitmap高效优化指南:从内存管理原理到现代压缩策略Bitmap优化就像“为照片科学瘦身”,核心是区分 - 掘金[ https://juejin.cn/post/7471168278888218633](https://juejin.cn/post/7471168278888218633) \[99] Android中图片压缩的三种实现方法\_Android\_脚本之家[ https://www.jb51.net/program/336601061.htm](https://www.jb51.net/program/336601061.htm) \[100] APK瘦身的方法-CSDN博客[ https://blog.csdn.net/u014686606/article/details/154749136](https://blog.csdn.net/u014686606/article/details/154749136) \[101] android 图片压缩 鲁班 PSNR\_mob64ca12d06991的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213300/13664634](https://blog.51cto.com/u_16213300/13664634) \[102] android apk内置图片压缩的好处\_mob649e816ab022的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16175525/13733097](https://blog.51cto.com/u_16175525/13733097) \[103] android中的图片如何适应不同分辨率的手机\_mob649e815e6170的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16175475/13416051](https://blog.51cto.com/u_16175475/13416051) \[104] android如何匹配不通分辨率的资源\_mob64ca12d9081f的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213335/13414004](https://blog.51cto.com/u_16213335/13414004) \[105] 画像のパフォーマンスの最適化[ https://developer.android.com/develop/ui/compose/graphics/images/optimization?hl=ja](https://developer.android.com/develop/ui/compose/graphics/images/optimization?hl=ja) \[106] Android高分辨率图片资源处理 - CSDN文库[ https://wenku.csdn.net/doc/1se17gxzi6](https://wenku.csdn.net/doc/1se17gxzi6) \[107] 【图片选择与兼容性难题破解】:Android头像适配避坑指南 - CSDN文库[ https://wenku.csdn.net/column/2sgd5yvg8s](https://wenku.csdn.net/column/2sgd5yvg8s) \[108] 告别手动放图片的噩梦!用AI 30秒搞定Android多分辨率适配Android drawable多分辨率资源处理耗时费 - 掘金[ https://juejin.cn/post/7522098508788678671](https://juejin.cn/post/7522098508788678671) \[109] 8款必试的高效便捷图片压缩工具[ https://a1.art/zh/blog/best-image-compressor.html](https://a1.art/zh/blog/best-image-compressor.html) \[110] 2025 年 7 款最佳免费图像压缩工具 | Small.im[ https://small.im/zh-hans/blog/best-image-compression-tools-2025](https://small.im/zh-hans/blog/best-image-compression-tools-2025) \[111] PNG图片压缩对比分析\_tinypng 压缩算法-CSDN博客[ https://blog.csdn.net/u014120638/article/details/53994231](https://blog.csdn.net/u014120638/article/details/53994231) \[112] APK瘦身的方法-CSDN博客[ https://blog.csdn.net/u014686606/article/details/154749136](https://blog.csdn.net/u014686606/article/details/154749136) \[113] TinyPNG – Compress WebP, PNG and JPEG images intelligently[ https://tinypng.com/index.html](https://tinypng.com/index.html) \[114] 2025年14款最佳图片压缩软体【照片档案缩小工具推荐】[ https://www.movavi.com/zh/learning-portal/best-image-compression-tools.html](https://www.movavi.com/zh/learning-portal/best-image-compression-tools.html) \[115] 磁盘清理工具-应用宝官网[ https://sj.qq.com/topic/200074643](https://sj.qq.com/topic/200074643) \[116] 内存检测工具-应用宝官网[ https://sj.qq.com/topic/200074497](https://sj.qq.com/topic/200074497) \[117] Avast Cleanup(手机清理)下载-Avast Cleanup新版本25.01.0-ROM之家下载[ https://m.romzhijia.net/app/AvastCleanupsjql\_364236.html](https://m.romzhijia.net/app/AvastCleanupsjql_364236.html) \[118] android studio有什么插件能够查找多余资源像图片或者xml或者strings字符串 - CSDN文库[ https://wenku.csdn.net/answer/6viahxr6qz](https://wenku.csdn.net/answer/6viahxr6qz) \[119] 超速清理-小米应用商店[ https://app.mi.com/details?id=com.hzkli.csqli](https://app.mi.com/details?id=com.hzkli.csqli) \[120] SDMaid官方版下载-SDMaid手机清理工具免费下载 v5.6.3安卓版-当快软件园手机版[ https://www.downkuai.com/android/123281.html](https://www.downkuai.com/android/123281.html) \[121] 深度清理手机内存软件推荐 手机卡顿必看的高效清理工具\_豌豆荚[ https://m.wandoujia.com/strategy/6133708429376346739.html](https://m.wandoujia.com/strategy/6133708429376346739.html) \[122] Ringkasan yang dapat digambar vektor[ https://developer.android.com/develop/ui/views/graphics/vector-drawable-resources?hl=ID](https://developer.android.com/develop/ui/views/graphics/vector-drawable-resources?hl=ID) \[123] Android矢量图形实现与动画技巧演示-CSDN博客[ https://blog.csdn.net/weixin\_36059856/article/details/149249437](https://blog.csdn.net/weixin_36059856/article/details/149249437) \[124] Android之Apk优化九道工序\_resguardrelease-CSDN博客[ https://blog.csdn.net/qq\_36347817/article/details/96108199](https://blog.csdn.net/qq_36347817/article/details/96108199) \[125] 🎨 Android View背景选择:Shape、PNG与SVG的奥秘为了让您快速了解 Shape Drawable、 - 掘金[ https://juejin.cn/post/7546051261582950442](https://juejin.cn/post/7546051261582950442) \[126] android svg 渲染慢\_mob649e815574e6的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16175438/12825132](https://blog.51cto.com/u_16175438/12825132) \[127] ภาพรวมเวกเตอร์ที่ถอนออกได้[ https://developer.android.com/develop/ui/views/graphics/vector-drawable-resources?authuser=0000\&hl=th](https://developer.android.com/develop/ui/views/graphics/vector-drawable-resources?authuser=0000\&hl=th) \[128] android APK瘦身大法——SVG图片瘦身\_svg 瘦身-CSDN博客[ https://blog.csdn.net/sw950729/article/details/61920576](https://blog.csdn.net/sw950729/article/details/61920576) \[129] Low-latency decoding in Media Codec[ https://source.android.com/docs/core/media/low-latency-media](https://source.android.com/docs/core/media/low-latency-media) \[130] 【性能优化】ffmpeg在android上的软编解码效率瓶颈分析与调优[ https://wenku.csdn.net/column/2vijasy002](https://wenku.csdn.net/column/2vijasy002) \[131] Android 16 将使媒体播放更加流畅 - 实时互动网[ https://www.nxrte.com/jishu/57259.html](https://www.nxrte.com/jishu/57259.html) \[132] Android硬编解码器选择对编码速度有何影响?\_编程语言-CSDN问答[ https://ask.csdn.net/questions/8887153](https://ask.csdn.net/questions/8887153) \[133] 基于大牛直播SDK的Android平台低延迟RTSP|RTMP播放与录像技术实践​技术背景 随着直播、安防监控、远程会议 - 掘金[ https://juejin.cn/post/7472956559176007690](https://juejin.cn/post/7472956559176007690) \[134] android ffmpeg 面试\_mob64ca12edad02的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213420/13738412](https://blog.51cto.com/u_16213420/13738412) \[135] AndroidX Media 1.8.0-alpha01 版本技术解析 - GitCode博客[ https://blog.gitcode.com/0752a97cadbdcc2accd81ee00ec50793.html](https://blog.gitcode.com/0752a97cadbdcc2accd81ee00ec50793.html) \[136] HlsMediaSource、DashMediaSource、 ProgressiveMediaSource差异详解 - 掘金[ https://juejin.cn/post/7545700885981446184](https://juejin.cn/post/7545700885981446184) \[137] 7步打造流畅播放体验:ExoPlayer网络栈深度优化指南-CSDN博客[ https://blog.csdn.net/gitblog\_01019/article/details/151330193](https://blog.csdn.net/gitblog_01019/article/details/151330193) \[138] 列表中item是视频,怎么优化它的打开速度0. 结论概览(按收益排序) 预加载下一条/上一条(先 prepare() 后 - 掘金[ https://juejin.cn/post/7548835244298240010](https://juejin.cn/post/7548835244298240010) \[139] HLS[ https://developer.android.com/media/media3/exoplayer/hls?authuser=0\&hl=he](https://developer.android.com/media/media3/exoplayer/hls?authuser=0\&hl=he) \[140] 在Flutter中实现视频流媒体播放时,如何有效降低首帧加载时间?[ http://bbs.itying.com/topic/685382054715aa0088480a99](http://bbs.itying.com/topic/685382054715aa0088480a99) \[141] Android PlayerView视频定帧\_mob6454cc743894的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16099298/13195016](https://blog.51cto.com/u_16099298/13195016) \[142] 10 Proven Ways to Optimize Android Apps for Smooth Video Streaming in 2025[ https://www.forasoft.com/blog/article/optimize-android-apps-video-streaming](https://www.forasoft.com/blog/article/optimize-android-apps-video-streaming) \[143] Android MediaLoader单行代码实现缓存视频/音频播放 - CSDN文库[ https://wenku.csdn.net/doc/3a27ct85fx](https://wenku.csdn.net/doc/3a27ct85fx) \[144] 9.2 MediaPlayer播放音频与视频 | 菜鸟教程[ https://www.runoob.com/w3cnote/android-tutorial-mediaplayer.html](https://www.runoob.com/w3cnote/android-tutorial-mediaplayer.html) \[145] Android音乐播放器数据管理革新:实现云端同步与本地存储的完美结合 - CSDN文库[ https://wenku.csdn.net/column/3qohtuuosj](https://wenku.csdn.net/column/3qohtuuosj) \[146] MediaLoader Cache video/audio while playing for any android me @codeKK Android开源站[ https://p.codekk.com/detail/Android/yangwencan2002/MediaLoader](https://p.codekk.com/detail/Android/yangwencan2002/MediaLoader) \[147] Android多媒体在线播放与图片预览下载功能实现 - CSDN文库[ https://wenku.csdn.net/doc/16m39vswoh](https://wenku.csdn.net/doc/16m39vswoh) \[148] android exoplayer 播放缓存和播放已下载文件\_mob64ca12ed7b35的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213419/12610747](https://blog.51cto.com/u_16213419/12610747) \[149] android exoplayer更好用的\_mob6454cc690811的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16099218/12337955](https://blog.51cto.com/u_16099218/12337955) \[150] 言語と地域の解決の概要[ https://developer.android.com/guide/topics/resources/multilingual-support?authuser=1\&hl=ja](https://developer.android.com/guide/topics/resources/multilingual-support?authuser=1\&hl=ja) \[151] 使用 Android App Bundle 极致压缩应用体积> 本文将通过原理剖析 + 完整代码 + 实战优化,带你彻底 - 掘金[ https://juejin.cn/post/7523041906269700111](https://juejin.cn/post/7523041906269700111) \[152] Builder打包apk本地化 - CSDN文库[ https://wenku.csdn.net/answer/6q18esfqx3](https://wenku.csdn.net/answer/6q18esfqx3) \[153] 动态功能模块与Release构建:Google Play拆分交付实战(节省30%安装体积的核心秘诀) - CSDN文库[ https://wenku.csdn.net/column/80tde83os9](https://wenku.csdn.net/column/80tde83os9) \[154] Поддержка разных языков и культур[ https://developer.android.com/training/basics/supporting-devices/languages.html?authuser=0\&hl=ru](https://developer.android.com/training/basics/supporting-devices/languages.html?authuser=0\&hl=ru) \[155] Language and locale resolution overview[ https://developer.android.com/guide/topics/resources/multilingual-support?authuser=4](https://developer.android.com/guide/topics/resources/multilingual-support?authuser=4) \[156] Descripción general del idioma y la configuración regional[ https://developer.android.com/guide/topics/resources/multilingual-support?authuser=9\&hl=es](https://developer.android.com/guide/topics/resources/multilingual-support?authuser=9\&hl=es) \[157] Android 包体积优化实践——入门级攻略通过系统化的优化策略,可显著降低包体积,提升用户下载意愿与应用性能。优化过程 - 掘金[ https://juejin.cn/post/7483449728393363468](https://juejin.cn/post/7483449728393363468) \[158] Android性能优化之包体积优化一、包体积组成与瓶颈分析 1. 典型 APK 结构占比 2. 核心瓶颈来源 资源冗余: - 掘金[ https://juejin.cn/post/7528257655611244544](https://juejin.cn/post/7528257655611244544) \[159] 利用Loquacious库实现Android动态资源加载以减小APK大小 - CSDN文库[ https://wenku.csdn.net/doc/79xqsf7g40](https://wenku.csdn.net/doc/79xqsf7g40) \[160] 【APK资源优化技巧】:精简高效,提升应用加载速度 - CSDN文库[ https://wenku.csdn.net/column/2g2m6h7j4k](https://wenku.csdn.net/column/2g2m6h7j4k) \[161] android 打包变 lib大了\_mob64ca12d5604e的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213320/12961221](https://blog.51cto.com/u_16213320/12961221) \[162] This One Build Setting Shrunk My APK by 40% — And I Almost Missed It 🤯[ https://www.droidcon.com/2025/08/12/this-one-build-setting-shrunk-my-apk-by-40-and-i-almost-missed-it-%F0%9F%A4%AF/](https://www.droidcon.com/2025/08/12/this-one-build-setting-shrunk-my-apk-by-40-and-i-almost-missed-it-%F0%9F%A4%AF/) \[163] Android 性能优化(四)优化Apk体积为什么需要做 Android 包体积优化 提高下载转化率,同类型的 App - 掘金[ https://juejin.cn/post/7477875236136386598](https://juejin.cn/post/7477875236136386598) \[164] Cómo crear varios APK[ https://developer.android.com/build/configure-apk-splits?authuser=1\&hl=es](https://developer.android.com/build/configure-apk-splits?authuser=1\&hl=es) \[165] Creare più APK[ https://developer.android.com/build/configure-apk-splits?hl=it](https://developer.android.com/build/configure-apk-splits?hl=it) \[166] Membuat beberapa APK[ https://developer.android.com/build/configure-apk-splits?authuser=9\&hl=id](https://developer.android.com/build/configure-apk-splits?authuser=9\&hl=id) \[167] Isolated Splits[ https://chromium.googlesource.com/ios-chromium-mirror/+/6d244f9bdc6568082333f39110454665de714638/docs/android\_isolated\_splits.md](https://chromium.googlesource.com/ios-chromium-mirror/+/6d244f9bdc6568082333f39110454665de714638/docs/android_isolated_splits.md) \[168] Split APK 是什么APK - CSDN文库[ https://wenku.csdn.net/answer/3xuck01qbn](https://wenku.csdn.net/answer/3xuck01qbn) \[169] android Parcelable自动生产插件\_mob64ca140a1f7c的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213657/13342540](https://blog.51cto.com/u_16213657/13342540) \[170] Android 插件化基础概念插件化的核心思想在于将 App 的各项功能模块拆分成独立的插件(通常是 APK 文件),主 - 掘金[ https://juejin.cn/post/7514682489325305894](https://juejin.cn/post/7514682489325305894) \[171] LibChecker:安卓应用架构分析专家一、软件简介 LibChecker 是一款专业的安卓应用架构分析工具,旨在帮助 - 掘金[ https://juejin.cn/post/7546977677473103899](https://juejin.cn/post/7546977677473103899) \[172] 推荐项目:依赖分析Gradle插件,为您的Android构建健康把脉-CSDN博客[ https://blog.csdn.net/gitblog\_01192/article/details/141454739](https://blog.csdn.net/gitblog_01192/article/details/141454739) \[173] com.autonomousapps.dependency-analysis[ https://plugins.gradle.org/plugin/com.autonomousapps.dependency-analysis/2.15.0](https://plugins.gradle.org/plugin/com.autonomousapps.dependency-analysis/2.15.0) \[174] 深度揭秘:高效构建利器 —— 依赖分析Gradle插件-CSDN博客[ https://blog.csdn.net/gitblog\_00042/article/details/138789246](https://blog.csdn.net/gitblog_00042/article/details/138789246) \[175] sbt-dependency-analyzer[ https://github.com/bitlap/sbt-dependency-analyzer](https://github.com/bitlap/sbt-dependency-analyzer) \[176] android dependency analyzer 用法\_mob64ca12da726f的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213341/13220424](https://blog.51cto.com/u_16213341/13220424) \[177] android系统 使用哪些工具可以分析组件间的依赖\_android中查看binary的依赖关系-CSDN博客[ https://blog.csdn.net/shi450561200/article/details/145861833](https://blog.csdn.net/shi450561200/article/details/145861833) \[178] Android 包体积优化实践——入门级攻略通过系统化的优化策略,可显著降低包体积,提升用户下载意愿与应用性能。优化过程 - 掘金[ https://juejin.cn/post/7483449728393363468](https://juejin.cn/post/7483449728393363468) \[179] Gradle分发包的内部解析Gradle分发包的内部解析 当看到有人问"Gradle分发包里有什么?"时,我最初觉得好笑 - 掘金[ https://juejin.cn/post/7547559094618750995](https://juejin.cn/post/7547559094618750995) \[180] Android应用瘦身教程:使用LibChecker分析与优化APK体积-CSDN博客[ https://blog.csdn.net/gitblog\_00988/article/details/151891898](https://blog.csdn.net/gitblog_00988/article/details/151891898) \[181] Shrink size of outputs on disk #1395[ https://github.com/autonomousapps/dependency-analysis-gradle-plugin/issues/1395](https://github.com/autonomousapps/dependency-analysis-gradle-plugin/issues/1395) \[182] APK瘦身的方法-CSDN博客[ https://blog.csdn.net/u014686606/article/details/154749136](https://blog.csdn.net/u014686606/article/details/154749136) \[183] android module存在不同版本依赖会使包体增加吗\_mob649e81586edc的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16175450/12722346](https://blog.51cto.com/u_16175450/12722346) \[184] 精益求精:Android应用体积优化的终极指南\_android 包体积优化-CSDN博客[ https://blog.csdn.net/u011897062/article/details/132967870](https://blog.csdn.net/u011897062/article/details/132967870) \[185] Weryfikacja zależności[ https://developer.android.com/build/dependency-verification?authuser=5\&hl=pl](https://developer.android.com/build/dependency-verification?authuser=5\&hl=pl) \[186] android 检查包冲突\_mob64ca12efd81c的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213429/13314407](https://blog.51cto.com/u_16213429/13314407) \[187] Could not resolve all dependencies for configuration ':launcher:debugRuntimeClasspath'\_编程语言-CSDN问答[ https://ask.csdn.net/questions/8818363](https://ask.csdn.net/questions/8818363) \[188] Android报错Error: Program type already present的依赖冲突-CSDN博客[ https://blog.csdn.net/shejizuopin/article/details/148398435](https://blog.csdn.net/shejizuopin/article/details/148398435) \[189] Cómo depurar errores de resolución de dependencias[ https://developer.android.com/build/dependency-resolution-errors?hl=es-419](https://developer.android.com/build/dependency-resolution-errors?hl=es-419) \[190] android 排除包里的重复依赖\_mob64ca12f7ae31的技术博客\_51CTO博客[ https://blog.51cto.com/u\_16213462/12959068](https://blog.51cto.com/u_16213462/12959068) \[191] Android 查看并解决重复依赖at com.android.builder.dexing.DexArchiveMer - 掘金[ https://juejin.cn/post/7460934174838063113](https://juejin.cn/post/7460934174838063113)

Android触摸事件传递机制详解

## Android触摸事件传递机制详解 Android触摸事件传递机制是UI交互的基础,它决定了用户触摸操作如何被系统识别并传递给正确的视图组件进行处理。这一机制遵循明确的传递路径和方法调用规则,确保事件能够被高效地分发和处理。**当用户触摸屏幕时,事件首先由底层硬件捕获,然后通过Android输入系统传递给应用层,最终沿视图层次结构从上到下传递,直到找到能够处理该事件的视图组件**。 ### 一、触摸事件类型与传递路径 Android触摸事件通过MotionEvent对象表示,主要包含三种基本动作类型:ACTION_DOWN表示手指首次接触屏幕;ACTION_MOVE表示手指在屏幕上移动;ACTION_UP表示手指离开屏幕 。此外,还存在ACTION_CANCEL表示事件被取消的情况。这些事件类型构成了完整的触摸交互序列,其中ACTION_DOWN是必须的,它标志着一次触摸事件的开始,而后续的ACTION_MOVE和ACTION_UP则可能根据用户操作出现多次或零次。 触摸事件的传递路径遵循责任链模式,从系统层到应用层,再到具体的视图组件 。**完整的传递路径为:底层硬件 → Android输入系统 → Activity → Window → DecorView → ViewGroup → View**。这一路径确保了事件能够被正确路由到需要处理它的视图组件。其中,Activity作为应用的顶层容器,是事件分发的起点;Window(通常为PhoneWindow)负责将事件传递给根视图;DecorView作为Activity的根视图,继承自FrameLayout,属于ViewGroup类型,会继续将事件分发给其子视图;最后,事件传递到具体的View组件进行处理。 ### 二、分发阶段:dispatchTouchEvent方法 **所有触摸事件首先通过dispatchTouchEvent()方法进行分发,这是事件传递的第一个阶段** 。该方法存在于所有视图组件(Activity、ViewGroup和View)中,作为事件传递的入口。当事件到达某个组件时,其dispatchTouchEvent()方法会被调用,决定事件是被当前组件处理还是传递给子组件。 在Activity中,dispatchTouchEvent()方法首先调用onUserInteraction()通知系统用户正在交互,然后通过窗体对象(window)将事件传递给根视图(DecorView) 。如果所有子视图都未处理事件,Activity可以调用自身的onTouchEvent()方法进行兜底处理。在ViewGroup中,dispatchTouchEvent()方法会进行额外的安全性过滤(通过onFilterTouchEventForSecurity()) ,并根据是否拦截(通过onInterceptTouchEvent())决定事件传递方向 。对于普通View,dispatchTouchEvent()方法主要负责将事件传递给自身的onTouchEvent()进行处理。 **该方法的返回值决定了事件传递的终止或继续** :返回true表示事件被当前组件消费,传递终止;返回false表示事件未被消费,可能继续向上传递;调用super.dispatchTouchEvent()表示按照默认逻辑处理事件,通常会继续传递给子视图或自身onTouchEvent()方法。 ### 三、拦截阶段:onInterceptTouchEvent方法 **onInterceptTouchEvent()是ViewGroup特有的方法,用于决定是否拦截子视图的事件** 。这是事件传递的第二个阶段,只有ViewGroup及其子类(如LinearLayout、RelativeLayout等)实现了这一方法,普通View和Activity没有此方法。默认情况下,ViewGroup不会拦截事件(返回false),但开发者可以通过重写此方法实现自定义的拦截逻辑。 当ViewGroup的dispatchTouchEvent()方法被调用时,系统会根据事件类型(特别是ACTION_DOWN事件)或当前是否有触摸目标,调用onInterceptTouchEvent()来判断是否需要拦截事件 。如果返回true,则表示拦截事件,后续事件将直接由该ViewGroup自身的onTouchEvent()方法处理,不再向下传递给子视图 。如果返回false或调用super.onInterceptTouchEvent(),则事件会继续向下传递给子视图 。 **拦截行为具有优先级**:一旦某个父ViewGroup在事件序列中拦截了事件(如处理了ACTION_DOWN),后续的ACTION_MOVE和ACTION_UP事件也会被该ViewGroup直接处理,不会再次调用onInterceptTouchEvent()进行拦截判断 。这种机制确保了一旦开始拦截,后续事件处理的一致性。 ### 四、消费阶段:onTouchEvent方法 **onTouchEvent()是事件传递的最终阶段,所有组件(Activity、ViewGroup和View)都实现了这一方法,用于实际处理触摸事件** 。当事件到达某个组件时,如果其dispatchTouchEvent()方法未消费事件且未拦截(返回false或调用super),则会调用该组件的onTouchEvent()方法进行处理。 在ViewGroup中,如果未拦截事件(onInterceptTouchEvent()返回false),则会将事件传递给子视图进行处理 。子视图处理事件时,同样会调用其自身的onTouchEvent()方法。如果子视图返回true表示消费了事件,则事件传递终止;如果返回false,则事件会向上传递到父ViewGroup,父ViewGroup再调用自身的onTouchEvent()方法处理 。这种向上回传的机制称为"冒泡",允许父组件处理未被子组件消费的事件。 **消费事件的关键规则**:只有消费了ACTION_DOWN事件的组件,才能接收同一触摸序列的后续事件(如ACTION_MOVE和ACTION_UP) 。如果某个组件在处理ACTION_DOWN时返回false,后续事件将不再传递给该组件。这一规则确保了触摸事件处理的一致性和效率。 ### 五、事件传递的完整流程 当用户触摸屏幕时,完整的事件传递流程如下: 1. **事件产生**:底层硬件检测到触摸操作,生成MotionEvent对象,并传递给Android输入系统。 2. **事件分发起点**:输入系统将事件传递给当前Activity的dispatchTouchEvent()方法 。 3. **窗口层处理**:Activity通过窗体对象(window)将事件传递给根视图(DecorView)的dispatchTouchEvent()方法 。 4. **视图组分发**:根视图(通常为ViewGroup类型)开始向下分发事件,通过遍历子视图寻找能够处理事件的组件 。 5. **拦截判断**:在ViewGroup的dispatchTouchEvent()方法中,调用onInterceptTouchEvent()判断是否拦截事件 。如果拦截(返回true),则事件由该ViewGroup自身的onTouchEvent()处理;如果不拦截(返回false),则继续向下传递。 6. **最终消费**:事件传递到最底层的View组件,调用其onTouchEvent()方法处理 。如果该View返回true表示消费了事件,事件传递终止;如果返回false,则事件向上传递到父ViewGroup,父ViewGroup再调用自身的onTouchEvent()方法处理。 这一流程确保了触摸事件能够被正确传递到需要处理它的组件,同时允许父组件在必要时拦截事件。 ### 六、事件传递的特殊场景与优化 **事件传递机制在某些特殊场景下会有不同的行为** 。例如,当手指移动距离超过系统阈值时,才会触发ACTION_MOVE事件;如果用户仅仅点击屏幕而没有移动,则只会触发ACTION_DOWN和ACTION_UP事件 。此外,Android系统会对事件传递进行优化,如在没有子视图消费事件的情况下,可能不会将后续事件再次传递给所有中间视图 。 **事件传递的效率优化**是系统设计的重要考量。当ViewGroup首次拦截事件(处理ACTION_DOWN)后,后续的ACTION_MOVE和ACTION_UP事件将直接由该ViewGroup处理,不再进行拦截判断 。这种机制减少了不必要的拦截判断,提高了事件处理效率。此外,系统还通过mFirstTouchTarget等内部机制跟踪处理事件的子视图,确保事件能够准确传递到正确的组件 。 理解Android触摸事件传递机制对于开发复杂的UI交互至关重要。通过合理重写dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()等方法,开发者可以精确控制事件传递路径,实现自定义的触摸交互逻辑。这一机制既保证了事件处理的灵活性,又确保了系统的效率和稳定性。

双非硕,Java 实习都被挂,拿到安卓实习犹豫是否要去?

# 1.个人情况: 我现在是**研二上学期**了,**双非硕**,坐标:武汉,我目前想早点出来找实习,现在只能找日常实习嘛,想着就近在武汉。 跟着鱼皮做了:**AI零代码生成平台**,**分布式API调用平台**,**鱼泡交友匹配**,**用户中心**。 # 2.找日常实习的情况: 我投了很久的简历,陆陆续续有一些面试 **Java后端日常实习**: (1).小米:进面了(感觉是运气好,小米缺人正好),八股很多没回答上来,就挂了。然后去疯狂背八股,每天刷算法。 (2). 然后各种武汉公司都投,JAVA后端、JAVA AI应用开发都投,大公司基本都没后续消息,但是陆陆续续有很多家**五百到一千人**这种规模的这种公司让我去线下面试,感觉都不怎么问我八股什么的,问的都很浅,反正到目前这些公司基本也都还没消息。 (3).可能有一个*电信外包的JAVA后端*要我, 需要自己带电脑,通勤四五十分钟,工资4000/月。要了我的学历证书,说正在向上面的公司(广州邮电)申请offer,但是目前还没有消息。 **安卓开发日常实习** 然后安卓岗位也试着投了,真有面试,面试前一天突击看了看安卓八股(以前有安卓项目): 情况如下:(我就投了两个,都进面了) (1).蔚来汽车[上海]:进面,基本都答出来了,算法也写出来了,但是发邮件被通知没过。 (2).斑马智行[武汉]:面试随便问了几个安卓问题,答的马马虎虎,然后收到offer了,每天通勤一个半小时,业务是做车载系统的。 **但是!!!**,我今天检查offer, 不是**斑马网络(boss上面沟通的确实是斑马网络的名义)**,offer上的而是**斑马智软(武汉)技术有限公司**的名义发的offer,我查了一下好像是**斑马网络**的全资子公司,2023年才成立的,感觉也可能有坑。然后让我这周四入职,工资:150/天, 感觉心里还是慌的。 **为什么会投安卓岗位**? 因为我们上一届的学长现在都在秋招说**Java特别卷**基本他们都进不了大厂,但是搞客户端的确很容易进大厂,刚好我大学的时候有过安卓开发的项目,于是我就也投了安卓。 # 3.现在的问题: 现在就是不知道如何抉择,这是我第一段实习,我感觉我要是去了以后肯定以后职业发展就走向安卓开发了,现在不知道是真的**不喜欢安卓开发,觉得没Java开发好** 还是一种 **第一次工作的恐惧带来的本能逃避**。 现在脑子就是两个想法打架 1: 不要去搞安卓开发,不然学这么久Java不就白费了,而且安卓开发以后发展还不知道怎么样。 2:去搞安卓开发,自己Java也没学好,以后怎么会竞争的过别人进大厂,毕竟安卓开发能够进大厂。 **********可能我自己也有点词不达意,没有表达清楚,心里就是慌。

安卓八股文

默写以下八股文 ps:下述内容为我个人默写过程,简化版,不保证准确性,仅供参考 **安卓四大组件是什么** 1、activity 2、service 3、广播接收器 ❌ 4、内容提供者 ❌ **重组?** activity在第一次运行的时候生成一颗视图树,每次状态改变的时候和视图树中的节点进行对比,看看是否改变了,如果改变了则进行重组,重新测量和定位,最终进行渲染。 **composable生命周期?** 重组: 删除: 子线程能否更新UI?为什么 不能更新,安卓不保证线程池安全,多个线程会导致绘制混乱 xm和compose的区别? xml是命令式:通过命令驱动UI ❌ compose是声明式:通过状态来驱动UI更新 Activity的生命周期 onCreate():初始化 onStart():启动态,处在后台 onRessume():进行聚焦,在页面显示 onPause():暂停态,动画停止❌ onStop():停止态, ondestroy:销毁态,进行资源清理 onReStart():重启态 Fragment的生命周期 和Activity进行关联 创建视图:❌ 销毁视图: 和Activity取消关联 谈谈Activity和Fragment的区别? 生命周期不同 Fragment切换时更流畅❌ ActivityA启动另一个ActivityB会调用哪些方法?如果B是透明主题的又或者是个DialogActivity呢? ActivityA的pause() 然后调用ActivityB的create -> start -> ressume() ActivityA的stop() ❌(stop应该在最后) 如果B是透明主题的又或者是个DialogActivity呢? 则不调用最后的stop() 什么是dp? 可以动态的根据屏幕密度计算像素值 px:像素单位 sp:字体样式,和dp类似 但是可以适配系统字体 谈一谈MVC、MVP、MVVM的理解? MVC:模型(负责数据)、视图(负责视图渲染)、控制器(负责业务逻辑的处理) MVP:MVC的变体,P指的是主持者,从模型中获取数据在视图中进行渲染 MVVM:数据和视图双向绑定 Activity和Fragment之间常见的几种通信方式? 1、实现接口 2、ViewModel 3、通过handler ❌ 说下横竖屏下Activity的生命周期?❌ 如果不配置configchange pause->stop->destory->create->start->ressume 进程间通信的方式 正常的有:管道、共享内存、消息队列、信号量、信号、套接字、文件等 安卓中使用binder,核心是binder驱动实现数据共享和通信 每个进程都有自己的binder,当向其他进程进行通信时则获取其他进程的binder引用。 然后通过binder引用向对方发送信息,binder驱动会将信息传递给目标进程进行处理,然后通过binder驱动器返回结果。❌ 线程间通信的方式?❌ 核心是通过handler,一个线程将消息发送到另一个线程的消息队列中 每个线程都有自己的looper和消息队列、handler 消息队列:存储信息 looper:不断循环从消息队列中获取信息,底层是epoll机制,然后分给对应的handler进行处理 handler:处理信息,放回目标线程的消息队列中 触摸事件传递过程:事件分发机制 从Activity->ViewGroup->View 从Activity开始,传递到ViewGroup,看看是否拦截,如果不拦截则接着往下传递 最终传递到view,如果仍然未消费的话则回溯。viewGroup是否消费,Activity是否消费。 安卓中一个电机事件点击结束后是怎么被销毁的? 事件分发机制中被消费掉 looper最多能开几个线程? 1个,一个looper对应一个线程和一个messageQueue handler的一个postDelay()方法知道吗? 用于延迟消费,设置消息的消费时间,到点则让looper取出来进行消费 如果创建了两个handler,如何知道哪个消息对应那个handler? 每个消息都会有自己绑定的handler 上下滑动事件和左右滑动事件的冲突如何处理? 在事件分发机制中的拦截器可以处理 recycleView了解吗?他是如何复用视图的?❌ 通过四级缓存? 一级缓存页面可见的 二级缓存页面可见范围附近的 三级缓存用户自定义的 四级缓存

Android 自定义系统服务初始化流程详解

# Android 自定义系统服务初始化流程详解 ## 1. 概述 自定义系统服务的初始化是一个系统化的过程,涉及多个组件和阶段的协同工作。下面是完整的初始化流程图和详细说明: ```mermaid flowchart TD A[定义AIDL接口] --> B[实现服务Stub] B --> C[创建SystemService] C --> D[在SystemServer中注册] D --> E[Context中添加常量] E --> F[权限配置] F --> G[SELinux策略] G --> H[构建配置] H --> I[系统启动时初始化] I --> J[启动阶段回调] J --> K[服务就绪] ``` ## 2. 详细初始化流程 ### 2.1 定义服务接口 (AIDL) 首先创建AIDL接口文件,这是定义服务契约的基础: ```java // frameworks/base/core/java/android/os/ICustomService.aidl package android.os; import android.annotation.Nullable; import android.annotation.NonNull; /** * @hide Custom service interface for advanced system operations */ interface ICustomService { // 示例方法:设置配置值 boolean setConfiguration(in String key, in String value); // 示例方法:获取配置值 String getConfiguration(in String key); // 示例方法:执行特定操作 int performOperation(in int operationId); } ``` ### 2.2 实现服务核心逻辑 创建服务的具体实现,继承自Stub类: ```java // frameworks/base/services/core/java/com/android/server/CustomService.java package com.android.server; import android.content.Context; import android.os.ICustomService; import android.util.Slog; import android.util.ArrayMap; import java.util.Map; public class CustomService extends ICustomService.Stub { private static final String TAG = "CustomService"; private final Context mContext; private final Map<String, String> mConfigurations = new ArrayMap<>(); // 单例实例 private static CustomService sInstance; public CustomService(Context context) { mContext = context; sInstance = this; Slog.i(TAG, "CustomService initialized"); // 初始化默认配置 initializeDefaultConfigurations(); } public static CustomService getInstance() { return sInstance; } private void initializeDefaultConfigurations() { mConfigurations.put("timeout", "5000"); mConfigurations.put("retry_count", "3"); mConfigurations.put("debug_mode", "false"); } @Override public boolean setConfiguration(String key, String value) { // 权限检查 mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_CUSTOM_SERVICE, "Requires MANAGE_CUSTOM_SERVICE permission"); if (key == null || value == null) { Slog.w(TAG, "setConfiguration: null key or value"); return false; } mConfigurations.put(key, value); Slog.d(TAG, "Configuration set: " + key + " = " + value); return true; } @Override public String getConfiguration(String key) { // 权限检查 mContext.enforceCallingOrSelfPermission( android.Manifest.permission.USE_CUSTOM_SERVICE, "Requires USE_CUSTOM_SERVICE permission"); return mConfigurations.get(key); } @Override public int performOperation(int operationId) { // 权限检查 mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_CUSTOM_SERVICE, "Requires MANAGE_CUSTOM_SERVICE permission"); Slog.i(TAG, "Performing operation: " + operationId); // 执行具体操作逻辑 switch (operationId) { case 1: return operation1(); case 2: return operation2(); default: Slog.w(TAG, "Unknown operation ID: " + operationId); return -1; } } private int operation1() { // 操作1的具体实现 return 100; } private int operation2() { // 操作2的具体实现 return 200; } // 系统启动阶段回调 public void onSystemReady() { Slog.i(TAG, "System is ready, performing final initialization"); // 系统就绪后的初始化操作 } // 启动完成回调 public void onBootCompleted() { Slog.i(TAG, "Boot completed, starting background operations"); // 启动后台任务等 } } ``` ### 2.3 创建SystemService包装器 为了更好的集成到系统服务生命周期中,创建SystemService包装器: ```java // frameworks/base/services/core/java/com/android/server/CustomSystemService.java package com.android.server; import android.content.Context; import android.util.Slog; import com.android.server.SystemService; public class CustomSystemService extends SystemService { private static final String TAG = "CustomSystemService"; private final CustomService mCustomService; public CustomSystemService(Context context) { super(context); mCustomService = new CustomService(context); Slog.i(TAG, "CustomSystemService created"); } @Override public void onStart() { Slog.i(TAG, "Publishing CustomService"); publishBinderService(Context.CUSTOM_SERVICE, mCustomService); publishLocalService(CustomService.class, mCustomService); } @Override public void onBootPhase(int phase) { Slog.d(TAG, "Boot phase: " + phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { // 系统服务就绪阶段 mCustomService.onSystemReady(); } else if (phase == PHASE_BOOT_COMPLETED) { // 启动完成阶段 mCustomService.onBootCompleted(); } } @Override public void onStartUser(int userHandle) { Slog.i(TAG, "Starting for user: " + userHandle); // 用户启动时的处理 } @Override public void onUnlockUser(int userHandle) { Slog.i(TAG, "Unlocking user: " + userHandle); // 用户解锁时的处理 } @Override public void onStopUser(int userHandle) { Slog.i(TAG, "Stopping user: " + userHandle); // 用户停止时的处理 } } ``` ### 2.4 在SystemServer中注册服务 在SystemServer的适当阶段启动自定义服务: ```java // frameworks/base/services/java/com/android/server/SystemServer.java public final class SystemServer { // ... private void startBootstrapServices() { // ... 其他引导服务 // 启动自定义服务(如果需要早期启动) try { traceBeginAndSlog("StartCustomService"); mSystemServiceManager.startService(CustomSystemService.class); traceEnd(); } catch (Throwable e) { reportWtf("starting CustomService", e); } } private void startOtherServices() { // ... 其他服务 // 或者在这里启动(如果不需要早期启动) try { traceBeginAndSlog("StartCustomService"); mSystemServiceManager.startService(CustomSystemService.class); traceEnd(); } catch (Throwable e) { reportWtf("starting CustomService", e); } // ... } } ``` ### 2.5 在Context中添加服务常量 ```java // frameworks/base/core/java/android/content/Context.java public abstract class Context { // ... /** * Use with {@link #getSystemService} to retrieve a {@link android.os.ICustomService} * for managing custom system operations. * * @see #getSystemService * @hide */ public static final String CUSTOM_SERVICE = "custom_service"; // ... } ``` ### 2.6 添加权限定义 ```xml <!-- frameworks/base/core/res/AndroidManifest.xml --> <permission android:name="android.permission.MANAGE_CUSTOM_SERVICE" android:protectionLevel="signature|privileged" android:label="@string/permlab_manageCustomService" android:description="@string/permdesc_manageCustomService" /> <permission android:name="android.permission.USE_CUSTOM_SERVICE" android:protectionLevel="normal" android:label="@string/permlab_useCustomService" android:description="@string/permdesc_useCustomService" /> ``` ### 2.7 添加SELinux策略 ```selinux # device/yourvendor/yourdevice/sepolicy/common/service_contexts custom_service u:object_r:custom_service:s0 # device/yourvendor/yourdevice/sepolicy/common/service.te type custom_service, system_api_service, system_server_service, service_manager_type; # device/yourvendor/yourdevice/sepolicy/common/system_server.te allow system_server custom_service:service_manager { add find }; allow system_server custom_service:binder { call transfer }; # device/yourvendor/yourdevice/sepolicy/common/your_app.te allow your_app custom_service:service_manager find; allow your_app custom_service:binder call; ``` ### 2.8 构建配置 在对应的Android.bp或Makefile中添加构建配置: ```bp // frameworks/base/Android.bp android_library { name: "custom-service", srcs: [ "services/core/java/com/android/server/CustomService.java", "services/core/java/com/android/server/CustomSystemService.java", ], libs: [ "android.app", "android.hardware", ], static_libs: [ "services.core", ], } ``` ## 3. 初始化阶段详解 ### 3.1 阶段1:类加载和实例化 ```java // SystemServiceManager启动服务时发生: CustomSystemService service = new CustomSystemService(context); // -> 创建CustomSystemService实例 // -> 创建CustomService实例 // -> 执行CustomService构造函数中的初始化 ``` ### 3.2 阶段2:服务发布 ```java // onStart()方法被调用时: publishBinderService(Context.CUSTOM_SERVICE, mCustomService); // -> 服务注册到ServiceManager // -> 现在其他进程可以通过ServiceManager.getService("custom_service")获取服务 ``` ### 3.3 阶段3:启动阶段回调 ```java // 系统启动过程中,不同阶段会调用onBootPhase() onBootPhase(PHASE_SYSTEM_SERVICES_READY); // 系统服务就绪 onBootPhase(PHASE_ACTIVITY_MANAGER_READY); // ActivityManager就绪 onBootPhase(PHASE_THIRD_PARTY_APPS_CAN_START); // 第三方应用可启动 onBootPhase(PHASE_BOOT_COMPLETED); // 启动完成 ``` ### 3.4 阶段4:用户相关回调 ```java // 多用户相关回调 onStartUser(int userHandle); // 用户启动 onUnlockUser(int userHandle); // 用户解锁 onStopUser(int userHandle); // 用户停止 ``` ## 4. 客户端访问方式 ### 4.1 系统组件访问方式 ```java // 通过ServiceManager直接访问 ICustomService customService = ICustomService.Stub.asInterface( ServiceManager.getService(Context.CUSTOM_SERVICE)); // 或者通过Context获取 CustomManager customManager = (CustomManager) context.getSystemService( Context.CUSTOM_SERVICE); ``` ### 4.2 创建CustomManager客户端 ```java // frameworks/base/core/java/android/os/CustomManager.java package android.os; import android.content.Context; import android.annotation.SystemService; import android.annotation.RequiresPermission; @SystemService(Context.CUSTOM_SERVICE) public class CustomManager { private final ICustomService mService; public CustomManager(Context context, ICustomService service) { mService = service; } @RequiresPermission(android.Manifest.permission.USE_CUSTOM_SERVICE) public String getConfiguration(String key) { try { return mService.getConfiguration(key); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @RequiresPermission(android.Manifest.permission.MANAGE_CUSTOM_SERVICE) public boolean setConfiguration(String key, String value) { try { return mService.setConfiguration(key, value); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } ``` ## 5. 调试和验证 ### 5.1 服务状态检查 ```bash # 检查服务是否注册 adb shell service list | grep custom # 检查服务运行状态 adb shell dumpsys custom_service # 检查权限设置 adb shell dumpsys package | grep -A5 -B5 custom ``` ### 5.2 日志监控 ```java // 在服务中添加详细的日志记录 Slog.d(TAG, "Service method called with params: " + parameters); Slog.w(TAG, "Unexpected condition: " + condition); Slog.e(TAG, "Error occurred: ", exception); ``` ## 6. 常见问题排查 1. **服务未注册**:检查SystemServer中添加服务的代码是否正确执行 2. **权限拒绝**:检查SELinux策略和权限定义 3. **绑定失败**:检查AIDL接口定义是否一致 4. **启动顺序问题**:确保服务在依赖的服务之后启动

Android SystemServer 中 Service 的创建和启动方式

今天导师给我将讲了一些如何新建一个系统服务,以及如何去初始化。 # Android SystemServer 中 Service 的创建和启动方式 在 Android 系统中,SystemServer 是系统服务的核心进程,负责启动和管理各种系统服务。以下是 SystemServer 中服务创建和启动的详细方式: ## 1. SystemServer 概述 SystemServer 是 Android 系统启动过程中的关键组件,它运行在 `system_server` 进程中,负责启动和管理所有核心系统服务。 ## 2. 服务启动流程 ### 2.1 主要启动阶段 SystemServer 的服务启动分为几个主要阶段: ```java // frameworks/base/services/java/com/android/server/SystemServer.java private void run() { // 1. 启动引导服务 (Bootstrap Services) startBootstrapServices(); // 2. 启动核心服务 (Core Services) startCoreServices(); // 3. 启动其他服务 (Other Services) startOtherServices(); // 4. 系统就绪后的回调 startSystemUi(context); systemReady(); } ``` ### 2.2 引导服务启动 ```java // frameworks/base/services/java/com/android/server/SystemServer.java private void startBootstrapServices() { // 启动 ActivityManagerService mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemProcess(); // 启动 PowerManagerService mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // 启动 PackageManagerService mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); // 更多引导服务... } ``` ### 2.3 核心服务启动 ```java private void startCoreServices() { // 启动 BatteryService mSystemServiceManager.startService(BatteryService.class); // 启动 UsageStatsService mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); // 启动 WebViewUpdateService mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); // 更多核心服务... } ``` ### 2.4 其他服务启动 ```java private void startOtherServices() { // 启动 WindowManagerService wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager); ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); // 启动 NotificationManagerService mSystemServiceManager.startService(NotificationManagerService.class); // 启动自定义服务(如你的 MDM 服务) try { traceBeginAndSlog("StartMdmPolicyManager"); mdmPolicyManager = new MdmPolicyManagerService(context); ServiceManager.addService(Context.MDM_POLICY_SERVICE, mdmPolicyManager); traceEnd(); } catch (Throwable e) { reportWtf("starting Mdm Policy Manager", e); } // 更多其他服务... } ``` ## 3. 服务创建方式 ### 3.1 使用 SystemServiceManager 启动 这是推荐的方式,适用于继承自 `SystemService` 的服务: ```java // 在 SystemServer 中 mSystemServiceManager.startService(YourService.class); // 服务类定义 public class YourService extends SystemService { public YourService(Context context) { super(context); } @Override public void onStart() { // 服务启动逻辑 publishBinderService(Context.YOUR_SERVICE, new YourBinder()); } @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_BOOT_COMPLETED) { // 启动完成后的操作 } } } ``` ### 3.2 直接实例化并注册 对于不继承 `SystemService` 的服务: ```java // 创建服务实例 YourService yourService = new YourService(context); // 添加到 ServiceManager ServiceManager.addService(Context.YOUR_SERVICE, yourService); // 或者使用带权限的添加方式 ServiceManager.addService(Context.YOUR_SERVICE, yourService, false, ServiceManager.DUMP_FLAG_PRIORITY_DEFAULT); ``` ### 3.3 使用静态 main 方法 某些服务有静态的 `main()` 方法: ```java // 服务类中的静态方法 public static YourService main(Context context) { YourService service = new YourService(context); ServiceManager.addService(Context.YOUR_SERVICE, service); return service; } // 在 SystemServer 中调用 YourService.main(mSystemContext); ``` ## 4. 服务生命周期管理 ### 4.1 启动阶段(Boot Phases) 系统服务可以在不同的启动阶段执行初始化: ```java public class YourService extends SystemService { // ... @Override public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { // 第三方应用可以启动时的初始化 } else if (phase == PHASE_BOOT_COMPLETED) { // 系统启动完成后的操作 } } } ``` ### 4.2 系统就绪回调 ```java private void systemReady() { // 通知所有服务系统已就绪 mActivityManagerService.systemReady(() -> { // 系统就绪后的操作 }, BOOT_TIMINGS_TRACE_LOG); } ``` ## 5. 自定义服务示例 以下是在 SystemServer 中添加自定义服务的完整示例: ### 5.1 服务接口定义 (AIDL) ```java // frameworks/base/core/java/android/app/IMyCustomService.aidl package android.app; interface IMyCustomService { void doSomething(int param); int getSomething(); } ``` ### 5.2 服务实现 ```java // frameworks/base/services/core/java/com/android/server/MyCustomService.java package com.android.server; import android.app.IMyCustomService; import android.content.Context; import android.os.IBinder; import android.util.Slog; public class MyCustomService extends IMyCustomService.Stub { private static final String TAG = "MyCustomService"; private final Context mContext; public MyCustomService(Context context) { mContext = context; Slog.i(TAG, "MyCustomService created"); } @Override public void doSomething(int param) { Slog.d(TAG, "doSomething called with param: " + param); // 实现具体功能 } @Override public int getSomething() { Slog.d(TAG, "getSomething called"); return 42; // 示例返回值 } } ``` ### 5.3 在 SystemServer 中启动服务 ```java // frameworks/base/services/java/com/android/server/SystemServer.java public final class SystemServer { // ... private void startOtherServices() { // ... // 启动自定义服务 try { traceBeginAndSlog("StartMyCustomService"); MyCustomService myCustomService = new MyCustomService(context); ServiceManager.addService(Context.MY_CUSTOM_SERVICE, myCustomService); traceEnd(); } catch (Throwable e) { reportWtf("starting My Custom Service", e); } // ... } } ``` ### 5.4 在 Context 中定义服务常量 ```java // frameworks/base/core/java/android/content/Context.java public abstract class Context { // ... public static final String MY_CUSTOM_SERVICE = "my_custom_service"; // ... } ``` ## 6. 注意事项 1. **启动顺序**:服务的启动顺序很重要,依赖其他服务的服务应该在依赖服务之后启动 2. **异常处理**:使用 try-catch 块捕获服务启动过程中的异常 3. **性能考虑**:避免在服务启动过程中执行耗时操作 4. **权限控制**:确保服务有适当的权限检查 5. **进程间通信**:如果服务需要跨进程访问,确保正确实现 Binder 接口 ## 7. 调试技巧 1. 使用 `dumpsys` 命令检查服务状态: ```bash adb shell dumpsys my_custom_service ``` 2. 查看服务列表: ```bash adb shell service list ``` 3. 检查系统日志: ```bash adb logcat -s SystemServer ``` 通过以上方式,你可以在 Android SystemServer 中成功创建和启动自定义系统服务。

学习过程中遇到的疑惑问了一下ai,分享出来一起学习一下

在 Android 框架层开发 `DreamInterfaceManager`、`DreamInterfaceService` 和 `DreamInterfaceManager.aidl` 时,它们之间的逻辑关系涉及 **Binder 跨进程通信(IPC)** 和 **服务管理**。这些组件通常用于系统级功能(如设备管理、策略控制等)。 --- ## **1. 组件职责与逻辑关系** | 组件 | 作用 | 关键逻辑 | |------|------|---------| | **`DreamInterfaceManager.aidl`** | **定义 Binder 接口**(客户端 ↔ 服务端通信协议) | 声明远程调用的方法(如 `setWifiPolicy(int)`),供客户端和服务端实现。 | | **`DreamInterfaceService.java`** | **系统服务实现**(运行在 `system_server` 进程) | 继承 `Service` 或 `SystemService`,实现 AIDL 接口的具体逻辑(如调用底层 HAL)。 | | **`DreamInterfaceManager.java`** | **客户端代理**(供 App 或系统模块调用) | 封装 Binder 调用,提供对外的 Java API(内部通过 `IDreamInterface` 调用 `DreamInterfaceService`)。 | --- ## **2. 调用流程(以 `setWifiPolicy(int)` 为例)** ```mermaid sequenceDiagram App/Framework->>DreamInterfaceManager: setWifiPolicy(1) DreamInterfaceManager->>DreamInterfaceService: Binder IPC (transact) DreamInterfaceService->>HAL/Driver: 执行底层操作(如 Wifi 策略设置) HAL/Driver-->>DreamInterfaceService: 返回结果 DreamInterfaceService-->>DreamInterfaceManager: Binder 返回结果 DreamInterfaceManager-->>App/Framework: 返回成功/失败 ``` --- ## **3. 关键实现步骤** ### **(1) 定义 AIDL 接口 (`DreamInterfaceManager.aidl`)** ```java // frameworks/base/core/java/android/server/DreamInterfaceManager.aidl package android.server; interface IDreamInterface { boolean setWifiPolicy(int policy); } ``` - 编译后生成 `IDreamInterface.java`(包含 `Stub` 和 `Proxy` 类)。 --- ### **(2) 实现服务端 (`DreamInterfaceService.java`)** ```java // frameworks/base/services/core/java/com/android/server/DreamInterfaceService.java public class DreamInterfaceService extends IDreamInterface.Stub { @Override public boolean setWifiPolicy(int policy) { // 实际逻辑(如调用 WifiManager) return true; } } ``` - **注册服务**(在 `SystemServer` 中): ```java // frameworks/base/services/java/com/android/server/SystemServer.java public void run() { ... mSystemServiceManager.startService(DreamInterfaceService.class); } ``` --- ### **(3) 实现客户端封装 (`DreamInterfaceManager.java`)** ```java // frameworks/base/core/java/android/server/DreamInterfaceManager.java public class DreamInterfaceManager { private final IDreamInterface mService; public DreamInterfaceManager(Context context) { // 获取 Binder 代理 mService = IDreamInterface.Stub.asInterface( ServiceManager.getService("dream_interface")); } public boolean setWifiPolicy(int policy) { try { return mService.setWifiPolicy(policy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } ``` --- ## **4. 常见问题与解决** ### **(1) `NullPointerException`(服务未注册)** - **原因**:`DreamInterfaceService` 未在 `SystemServer` 中启动,或客户端未正确获取 Binder 引用。 - **解决**: ```java // 检查服务是否注册 ServiceManager.checkService("dream_interface"); // 或确保 SystemServer 中调用了 startService() ``` ### **(2) `SecurityException`(权限不足)** - **原因**:未在 `AndroidManifest.xml` 或 SELinux 策略中声明权限。 - **解决**: - 在 `DreamInterfaceService` 中添加 `@RequiresPermission` 注解。 - 更新 `sepolicy` 规则(如 `hal_dream_interface_default.te`)。 ### **(3) Binder 调用超时** - **原因**:服务端阻塞(如死锁或耗时操作)。 - **解决**: ```java @Override public boolean setWifiPolicy(int policy) { // 异步执行或优化耗时逻辑 return true; } ``` --- ## **5. 扩展建议** - **使用 `HIDL`/`AIDL` HAL**:如果涉及硬件操作,建议通过 HAL 层实现。 - **添加 SELinux 策略**:确保 `system_server` 和客户端有权限访问服务。 - **日志与调试**:在 `DreamInterfaceService` 中添加 `Slog` 以便追踪问题。 如果需要更具体的实现细节(如 SELinux 规则或 HAL 集成),可以进一步讨论!

安卓基础学习总结

安卓学习总结 Android系统四大组件 (1)活动(Activity):是所有Android应用程序的门面,凡是在应用中你看得到的东西,都是放在活动中的。 (2)服务(Service):你无法看到它,但它会一直在后台默默地运行,即使用户退出了应用,服务仍然是可以继续运行的。 (3)广播接收器(Broadcast Receiver):广播接收器允许你的应用接收来自各处的广播消息,比如电话、短信等,当然你的应用同样也可以向外发出广播消息。 (4)内容提供器(Content Provider):为应用程序之间共享数据提供了可能,比如你想要读取系统电话簿中的联系人,就需要通过内容提供器来实现。 Activity Activity四种状态,七个回调方法,三种生存期,四种活动启动模式 运行:当一个活动位于返回栈的栈顶时,这时活动就处于运行状态。 暂停:当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。只有在内存极低的情况下,系统才会去考虑回收这种活动。 停止:当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。当其他地方需要内存时,处于停止状态的活动有可能会被系统回收。 销毁:当一个活动从返回栈中移除后就变成了销毁状态。系统会最倾向于回收处千这种状态的活动,从而保证手机的内存充足。 onCreate():在活动第一次被创建的时候调用。在这个方法中完成活动的初始化操作,比如说加载布局、绑定事件等。 onStart():在活动由不可见变为可见的时候调用。 onResume():在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。 onPause():在系统准备去启动或者恢复另一个活动的时候调用。执行后仍然可见但不可交互。 onStop():在活动完全不可见的时候调用。执行后不可见。 onDestory():在活动被销毁之前调用,之后活动的状态将变为销毁状态。 onRestart():在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。 完整生存期:活动在onCreate()方法和onDestroy()方法之间所经历的,就是完整生存期 可见生存期:活动在onStart()方法和onStop()方法之间所经历的,就是可见生存期。 前台生存期。活动在onResume()方法和onPause()方法之间所经历的就是前台生存期。 活动的四种启动方式 standard: 在standard 模式(即默认情况)下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。 singleTop: 在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。 singleTask: 每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。 single Instance: 会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都 共用的同一个返回栈,也就解决了共享活动实例的问题。 Android四种基本布局 线性布局(LinearLayout): 会将它所包含的控件在线性方向上依次排列 android:orientation:指定vertical是垂直方向排列 ,指定horizontal ,控件就会在水平方向上排列。 android:layout_gravity:指定控件在布局中的对齐方式 android:gravity:用于指定文字在控件中的对齐方式 android: layout_weight:系统会先把LinearLayout下所有控件指定的layout_weight值相加,得到一个总值,然后每个控件所占大小的比例就是用该控件的layout_weight值除以刚才算出的总值。 相对布局(RelativeLayout): 通过相对定位的方式让控件出现在布局的任何位置 android:layout_alignParentLeft:表示让一个控件位于其父控件的左侧 android:layout_alignParentTop:表示让一个控件位于其父控件的顶部 android: layout_alignParentRight:表示让一个控件位于其父控件的右侧 android:layout_alignParentBottom:表示让一个控件位于其父控件的底部 android:layout_centerInParent:表示让一个控件位于其父控件的中间 android:layout_above:表示让一个控件位于另一个控件的上方 android:layout_below:表示让一个控件位于另一个控件的下方 android:layout_toleftOf:表示让一个控件位于另一个控件的左侧 android:layout_toRightOf:表示让一个控件位于另一个控件的右侧 android:layout_alignLeft:表示让一个控件的左边缘和另一个控件的左边缘对齐 android:layout_alignRight:表示让一个控件的右边缘和另一个控件的右边缘对齐 帧布局(FrameLayout): 没有方便的定位方式,所有的控件都会默认摆放在布局的左上角 android:layout_gravity:指定控件在布局中的对齐方式 百分比布局(PercentFrameLayout和PercentRelativeLayout): 允许直接指定控件在布局中所占的百分比 添加依赖“com.android.support:percent:24.2.1" app:layout_widthPercent:表示确定控件宽度在父控件中所占比例 app:layout_heightPercent:表示确定控件高度在父控件中所占比例 绝对布局(AbsoluteLayout): 表格布局(TableLayout): Fragment四种状态,重要回调方法,生命周期 运行:当一个碎片是可见的,并且它所关联的活动正处千运行状态时,该碎片也处于运行状态。 暂停:当一个活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进入到暂停状态。 停止:当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态,或者通过调用FragmentTransaction 的remove()、replace()方法将碎片从活动中移除,但如果在事务提交之前调用addToBackStack()方法,这时的碎片也会进入到停止状态。总的来说,进入停止状态的碎片对用户来说是完全不可见的,有可能会被系统回收。 销毁:碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。或者通过调用FragmentTransaction 的remove() 、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的碎片也会进入到销毁状态。 onAttach():当碎片和活动建立关联的时候调用 onCreateView():为碎片创建视图(加载布局)时调用 onActivityCreated():确保与碎片相关联的活动一定已经创建完毕的时候调用 onDestroyView():当与碎片关联的视图被移除的时候调用 onDetach():当碎片与活动解除关联的时候调用其他 广播接 收器(Broadcast Receiver) 广播包括标准广播和有序广播 按方式分为全局广播和本地广播 本地广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播。 本地广播的优势: 可以明确地知道正在发送的广播不会离开我们的程序,因此不必担心机密数据泄漏。 其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患。 发送本地广播比发送系统全局广播将会更加高效。 前者是异步操作,后者则是同步操作,后者可以在标签里面添加优先级就可以保证广播的有序发送和接收了。 广播注册也包括两种动态注册和静态注册 注册广播的方式一般有两种,在代码中注册 和在AndroidManifest.xml中注册,其中前者也被称为动态注册,后者也被称为静态注册。 动态注册只需要新建一个类,让它继承自 BroadcastReceiver ,并重写父类的onReceive() 方法就行了。最后要取消注册,即在onDestroy()方法中来进行取消。但有一个弊端就是只能在程序启动的时候才能接收到广播。 静态注册则解决了这个问题,静态注册只需要在AndoridManifest.xml文件中写入<receiver>标签并在 标签里添加了相应的action。另外,监听系统开机广播 也是需要声明权限的,可以看到,我们使用 标签又加入了一 条android.permission.RECEIVE_BOOT_COMPLETED 权限。 内容提供器(Content Provider) 概念和优点: 主要用于在不同的应用程序之间实现数据共享的功能,它提供 了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全 性。目前,使用内容提供器是Android实现跨程序共享数据的标准方式。 不同于文件存储和SharedPreferences存储中的两种全局可读写操作模式,内容提供器可以选择只 对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。 两种用法: 使用现有的内容提供器来读取和操作相应程序中的数据。 借助该类ContentResolver。通过Context中的getContentResolver() 方法获取到该类的实例。 ContentResolver中提供了一系列的方法用于对数据进行CRUD操作,区别是接收的参数是URi(内容URI) 创建自己的内容提供器给我们的程序的数据提供外部访问接口。 新建一个类去继承ContentProvider,重新该类下面的六个方法。 了解活动和内容提供者是如何联系的 前者编写一个页面,添加一些按钮等功能,当点击按钮之后会通过一个uri,通过使用 ContentProvider 类里面的getContentResolver 方法来传递和操作对应的数据内容,同时内容提供者是实现了ContentProvider 类,同时继承了里面的六个方法,可以根据对应的uri来进行区分操作对应的数据,可以保证将数据共享出去。 服务(Service) 是Android中实现程序后台运行的解决方案,它非常适合去执行那些不需要和用 户交互而且还要求长期运行的任务。 解析异步消息处理机制 01. Message Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交 换数据。 02. Handler Handler顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是 使用Handler的sendMessage() 方法,而发出的消息经过一系列地辗转处理后,最终会传 递到Handler的handleMessage() 方法中。 03. MessageQueue MessageQueue是消息队列的意思,它主要用于存放所有通过Handler发送的消息。这部分消 息会一直存在于消息队列中,等待被处理。每个线程中只会有一个MessageQueue 对象。 04. Looper Looper是每个线程中的MessageQueue的管家,调用Looper的loop() 方法后,就会进入到一 个无限循环当中,然后每当发现MessageQueue中存在一条消息,就会将它取出,并传递到 Handler的handleMessage() 方法中。每个线程中也只会有一个Looper 对象。 首先需要在主线程当中创建一个Handler 对象,并重写 handleMessage() 方法。然后当子线程中需要进行UI操作时,就创建一个Message 对象,并 通过Handler将这条消息发送出去。之后这条消息会被添加到MessageQueue的队列中等待被处 理,而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回Handler的 handleMessage() 方法中。由于Handler是在主线程中创建的,所以此时handleMessage() 方法中的代码也会在主线程中运行。 服务的生命周期如下: onCreate() 、onStartCommand() 和onDestroy() 这3 个方 法,。 其中onCreate() 方法会在服务创建的时候调用 onStartCommand() 方法会在每次服务启动的时候调用 onDestroy() 方法会在服务销 毁的时候调用。 一般的服务是后台服务,创建前台服务的方法也很简单 Notification notification = new NotificationCompat.Builder(this) .setContentTitle("This is content title") .setContentText("This is content text") .setWhen(System.currentTimeMillis()) .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) .setContentIntent(pi) .build(); startForeground(1, notification); 安卓的网络技术的使用 主要包括两种自带的网络请求: :HttpURLConnection和HttpClient ( 在Android 6.0系统之后已废除) 开源项目 OkHttp 操作很方便,更简单易用。 解析XML格式和json数据 的方式 学习安卓的服务service相关概念和实战 服务(Service)是Android中实现程序后台运行的解决方案,它非常适合去执行那些不需要和用 户交互而且还要求长期运行的任务。 项目总结 PagerAdapter 一个用于 ViewPager 的自定义 PagerAdapter,主要作用是实现 无限循环轮播 的效果。 这个适配器适用于简单的无限轮播场景,比如Banner广告、引导页,优点是代码简洁,直接复用现有视图。但对于复杂场景,建议考虑更优化的方案,比如RecyclerView 或第三方库如 ViewPager2 ImageView 是用于在界面上展示图片的一个控件,它可以让我们的程序界面变得更加丰富多彩。BaseAdapter 是 Android 中一个 抽象基类,用于为 ListView、GridView、Spinner 等列表型控件提供数据适配功能。它是所有 Adapter 的父类,定义了 Adapter 的核心行为规范。 Intent数据回传 由于在一个活动中有可能调用startActivityForResult()方法去启动很多不同的活动,每一个活动返回的数据都会回调到onActivityResult()这个方法中,因此我们首先要做的就是通过检查requestCode的值来判断数据来源。确定数据是从SecondActivity返回的之后,我们再通过resultCode的值来判断处理结果是否成功。最后从data中取值并打印出来,这样就完成了向上一个活动返回数据的工作。 onActivityResult()方法带有3个参数: 第一个参数requestCode, 即我们在启动活动时传入的请求码。 第二个参数resultCode, 即我们在返回数据时传入的处理结果。 第三个参数data, 即携带着返回数据的Intent。 bug修复 天气项目成功解决所有问题,目前可以正常启动 前期主要卡顿的两个点 1,LitePal依赖不能成功拉取下来,后续直接通过jar包的方式来拉取依赖 2,省份和城市不能正确显示,主要的原因是安卓设备没有联网导致的网络不通,不能正确响应数据 3,另外就是点击天气不能正确回显,发现问题主要是网络响应的数据返回错误。 每次选择城市进行天气的选择时候,都会走缓存导致主页的城市都是缓存的,以至于出现bug 寻找了两种思路 1.每次设置缓存的时候设置缓存时间,查询的时候会判断缓存是否过期,如果过期重新从网络查询。 2,直接根据 instanceof 关键字可以用来判断一个对象是否属于某个 类的实例 ,如果还是主活动的实例则直接按照原本逻辑,否则重新查询当地天气

不写代码,让 AI 生成手机 APP!保姆级教程

你现在看到的 APP,是我完全用 AI 生成的,一行代码都没写!怎么做到的呢? ![](https://pic.code-nav.cn/post_picture/1601072287388278786/bX1dCDFiMxN4GxGo.webp) 大家好,我是程序员鱼皮。AI 发展很快,现在随随便便就能生成一个网站,但是怎么纯用 AI 开发能在手机上运行的 APP 呢?网上基本上没有完整的教程。所以,我出手了,下面只用几分钟的时间,我会教大家如何利用 AI 生成 APP,依然是 **保姆级教程**。 ⭐️ 本文对应视频,推荐观看:[https://bilibili.com/video/BV17HMcziEye](https://www.bilibili.com/video/BV17HMcziEye/) 下面有请我们的主角 `Cordova`! ## 一、什么是 Cordova? Apache Cordova 是一个开源的移动应用开发框架,允许开发者使用 HTML、CSS 和 JavaScript 等 Web 技术开发 **跨平台** 的移动应用。它通过将 Web 技术封装在本地容器中,使得开发者可以编写一次代码,然后在 Android、iOS、Windows 等多个平台上运行。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/SKyNNvtlZn5RXJlT.webp) Cordova 主要基于以下几个核心组件实现,感兴趣的同学可以了解一下: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/JW6k5RuUkjok2Bg5.webp) 也就是说,想要开发 APP,我们只需要把网站文件交给 Cordova,根据需要装一装插件、改一改配置,然后直接使用它提供的构建工具就能将 Web 应用打包成原生 APP 应用了(比如 APK 文件)!几乎不涉及任何代码编写和开发。 听起来很简单,有手就行?但是想使用 Cordova 开发 APP,必须要在电脑上安装对应的环境,比如 Android 和 IOS,而安装环境的难度可以说是 **非常炸裂** 了! 如果你自己折腾,可能至少要花个几天的时间,会踩很多坑,到网上搜各种方案还不一定能搞定。所以我才做了这个教程,该踩的坑我都帮大家踩完了,会 **用最短的时间带你搞定环境,并且教你如何使用 AI + Cordova 生成 APP**。开始之前记得 **点赞收藏三连** 哦,拜托,我的头发真的不多啦! ![](https://pic.code-nav.cn/post_picture/1601072287388278786/5SJxJnNlQUXp8Rvp.webp) ## 二、环境准备 ### 安装 Cordova 首先我们要安装 Cordova。Cordova 的运行依赖 Node.js 和 NPM 前端工具,到 [Node.js 官网](https://nodejs.org/zh-cn) 下载即可,会自动安装 NPM。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/KJxTNAHrPd48J1hL.webp) 可以把 NPM 理解为快速安装各种软件的小工具,安装完成后打开终端,执行下列命令安装 Cordova: ```bash npm install -g cordova ``` Cordova 支持将网站打包为 Android 和 IOS 移动端、Electron 桌面端应用。下面鱼皮带大家安装我个人认为难度最大的 **Android 环境**。注意,接下来的每一步,操作其实都不难,但是一定要仔细看!一个细节不注意可能就报错了! ### 安装 Android 环境 首先,我们要根据 Cordova 的版本来确定所需环境和工具的版本,由于我们安装的 Cordova 是最新版本的,因此直接阅读 [最新的官方文档](https://cordova.apache.org/docs/en/dev/guide/platforms/android/index.html) 即可,比如我这里需要的依赖如下: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/uOlGQU6K0OXWXttq.webp) 其中,最重要的是: - Java 17 - Gradle 8.13 - Android API 级别 >= 24 下面我们分别安装这些依赖。 #### 1、安装 Java Java 版本必须是 17,最好找个现成的 [Windows 系统的 Java 安装包](https://www.azul.com/downloads/?version=java-17-lts&os=windows&package=jdk#zulu): ![](https://pic.code-nav.cn/post_picture/1601072287388278786/3IVOga2jyXeXaLK7.webp) 安装 Java 时建议选择 **自动配置环境变量**(包括 Path 和 JAVA_HOME),就不用自己手动配置环境变量了。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/66fSiR2zK6hIInaa.webp) 安装完成后,打开终端执行 `java -version` 命令查看版本号,看到下列输出表示成功: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/q8vOYmYGzVQOpCpZ.webp) 如果无法执行命令,大概率是没有配置 Path 环境变量。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/9yHhrrWZBTPpulpA.webp) #### 2、安装 Gradle 根据上面的版本号,Gradle 必须是 8.13,直接到 [官网](https://gradle.org/releases/) 下载二进制压缩包即可。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/MGlnCXl1oBehhnqM.webp) 解压下载完成的压缩包,移动到 **不包含中文的路径** 中,然后配置环境变量,包括 Path 和 GRADLE_HOME: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/qcVDfWyX6ZDDczN5.webp) ![](https://pic.code-nav.cn/post_picture/1601072287388278786/1M6l1vhhURpGXUgk.webp) 打开终端执行 `gradle -v` 命令,查看版本号: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/jXzLT7plwQNhrPFN.webp) 如果命令无法执行,大概率是 Path 环境变量配置错误。 #### 3、安装 Android 建议直接安装 Android 开发工具 [Android Studio](https://developer.android.com/studio?hl=zh-cn),会自动安装 Android 的开发 SDK 和运行环境。 到官网下载 Android studio,运行安装包,按照步骤安装即可: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/xR28v46ptu3xVJoz.webp) 安装完成后,第一次打开 Android Studio 时,会提醒你安装 Android SDK 环境: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/5pB9wNUF2Nqkw5tU.webp) 注意不要把 SDK 组件安装到包含中文的目录下,好在安装包也给了限制,不然又得栽倒一片人。。。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/h24chaRCRCWYuMwx.webp) 接下来无脑安装即可,会自动安装各种 Android 开发常用的工具、还有安卓设备模拟器: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/qXVPP8tzJmh7ADjJ.webp) 这一步可能会有点煎熬,有些地区的朋友可能需要一些特殊的网络支持,你懂的。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/MY3SpyrrwYfubEKp.webp) ![](https://pic.code-nav.cn/post_picture/1601072287388278786/wDyPKXLVzxkrO3R5.webp) 经过了漫长的等待,Android SDK 终于安装完成,然后需要配置 Android 的环境变量 ANDROID_HOME: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/Mgo92C21SI45k75l.webp) 还要配置 platform-tools 到 Path 中,里面有一些命令行工具: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/PgAtPUkFqWxbMBxE.webp) 配置完成后,我们打开 Android Studio,右上角进入 SDK Manager 的设置,根据 Cordova 的版本号要求,安装对应 API Level 的 SDK,比如我这里安装了 34 和 35 版本。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/Hz3pH1XyIl4mYWTY.webp) 这一步可能也会比较慢,耐心等待安装吧~ ![](https://pic.code-nav.cn/post_picture/1601072287388278786/K3j1KfRAf6OWNoCK.webp) 安装完 SDK 后,再进入 SDK 工具选项,安装 Command-line Tools 命令行工具,之后在电脑上运行安卓 apk 包时可能会用到: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/vmr9ptTGa7qu37KM.webp) 同样,把 Command-line Tools 添加到环境变量 Path 中,路径为 `%ANDROID_HOME%\cmdline-tools\latest\bin`,这样一来,很多工具可以直接在终端中使用了,比如 apkanalyzer。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/RFCn4owE0oqqz5hN.webp) #### 4、安装 Android 设备模拟器 下面我们要尝试在自己的电脑上运行 Android 手机模拟器,这样调试程序更方便。 打开 Android Studio 的设备管理器,添加一个新设备: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/VF2QxueBFlSC51MZ.webp) 选择指定机型,建议选择 API 版本高一点的,我这里选择 Pixel 7: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/gUcja5SXOcPpqnp7.webp) 安装推荐的系统镜像: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/7d36iRH4G7c5N8Ss.webp) 耐心等待后手机就创建成功了,直接运行: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/yM91EsNrbd1OXc5I.webp) 结果,报错啦! ![](https://pic.code-nav.cn/post_picture/1601072287388278786/bKntmqys6rgbQo1R.webp) 如果你也遇到这种情况,可以在终端 **进入 Android 模拟器目录** 手动运行虚拟设备,这样能够看到详细的错误信息,有利于排查问题。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/I1ddDooDd3XfBsKV.webp) 比如我这里显然是由于路径包含了中文!可恶啊,当时年少轻狂不自卑一个没注意用了中文路径。。。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/uqEP6UNMyUO7Ntr2.webp) 解决方法很简单,手动创建一个不包含中文路径的 avd 虚拟设备目录,然后设置环境变量 ANDROID_SDK_HOME: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/ylH6tL77a7cFsqpo.webp) 然后再利用 Android Studio 创建一个设备并运行,这次成功运行了,恭喜你多了一个手机! ![](https://pic.code-nav.cn/post_picture/1601072287388278786/5AYUxx2HDoGrnbMB.webp) 至此,环境终于搞定了,下面来实战 AI + Cordova 开发 APP。 ## 三、AI + Cordova 实战 ### 创建项目 打开终端,进入你想要创建项目的目录,先执行 `cordova create` 命令来创建项目: ```bash cordova create <你的项目英文名称> ``` 首次创建项目可能会有提示: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/58gKkkLPvxmawhrK.webp) ### 生成代码 此处有 2 种生成模式: 1. 先创建 Cordova 项目,然后在该项目内进行 AI 代码生成。告诉 AI 你要创建一个兼容 Cordova APP 的网站,直接让 AI 生成兼容 APP 的代码。这样做的好处是生成的代码 **可以使用 Cordova 插件调用系统原生的能力**,比如调用相机进行拍照。 2. 在 Cordova 项目外单独用 AI 生成网站项目,AI 不会关心你是否要把项目转为 Cordova APP,然后再把生成好的网站移动到 Cordova 项目中。这样做的好处是生成的网站代码更容易运行,同样 **适合你已经有现成网站项目** 的场景。 下面两种方式我都会给大家演示,先讲第一种模式,直接让 AI 生成一个【表情包生成器】的 Cordova APP。 用 Cursor 打开刚刚创建的 Cordova 项目目录,给 AI 输入下列提示词,提示词中需要包含 Cordova,并且提到 **兼容性**: ```shell 请帮我开发一个【移动端表情包生成器】Web APP,使用纯前端技术 + Cordova 实现。 如果需要,你可以通过 Cordova 调用系统原生功能。 请生成完整的项目代码,确保功能完整可用,而且所有功能都需要同时兼容网页端和移动设备。 ## 📋 功能需求 ### 1. 图片获取 - 支持摄像头拍照 - 支持从本地选择图片文件 - 自动缩放图片到合适尺寸 ### 2. 表情包模板 - 提供8-10个常用表情包模板(惊呆了、无语、赞、点赞、emo了等) - 网格布局展示模板,点击选择应用 ### 3. 文字编辑 - 输入自定义文字内容 - 调整字体大小(20px-50px) - 选择文字颜色(白色、黑色、红色等基础色彩) - 添加文字描边效果 - 拖拽移动文字位置 ### 4. 贴纸功能 - 提供常用emoji表情贴纸(😂🤣😭😍🤔等5-10个) - 提供简单装饰贴纸(星星、爱心、箭头等) - 支持拖拽移动和简单缩放 ### 5. 保存功能 - 将编辑后的表情包导出为图片 - 支持下载保存到本地 ## 🎨 界面要求 - 移动端优先:适配手机屏幕,大按钮设计 - 页面布局: - 主页:拍照按钮、选择图片按钮 - 编辑页:顶部工具栏 + 中央画布 + 底部功能区 - 操作简单:实时预览效果,一键保存 ## 📱 操作流程 1. 拍照或选择图片 2. 选择表情包模板 3. 编辑文字内容和样式 4. 添加emoji或装饰贴纸 5. 预览效果并保存图片 ``` AI 生成的网站文件会放到 `www` 目录下。生成代码完成后,AI 可能会自动提醒你打包 APP 并且运行的命令,要依次添加安卓平台、安装插件、打包、运行。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/jCbomcH7l5QxVYEH.webp) 这些命令我们等会儿就会用到,现在先不要自动执行,因为生成的代码不一定直接可用,我们需要先利用网页端进行调试。 ### 网页浏览 可以直接双击生成的 HTML 文件 `www/index.html` 查看效果;当然,更推荐的是通过 cordova 命令添加平台并运行。 先添加浏览器平台: ```shell cordova platform add browser ``` 如果你在执行命令时遇到了报错,可以直接问 AI,比如鱼皮遇到了缺少命令执行权限的错误: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/iZb0ovMMzLhIHEG9.webp) 解决方案是,执行下列命令来修改 PowerShell 的执行策略: ```bash Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser ``` 添加平台成功后,可以输入 `cordova run` 命令运行平台: ```bash cordova run browser ``` 然后就能够查看到网站的运行效果了。需要注意的是,因为 Cordova Browser 平台的特殊性,通过这个命令运行的网页效果可能和直接双击、或者启动本地服务器运行有区别。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/yZWkAJ07SWExvRW3.webp) 除了上面的命令外,如果你想快速调试多个不同的平台,可以运行下列命令,统一查看各个平台: ```bash cordova serve --port 8000 ``` ![](https://pic.code-nav.cn/post_picture/1601072287388278786/aXAbJ2aoGNhQRy78.webp) ### 添加安卓平台 接下来执行类似的命令来添加安卓平台: ```bash cordova platform add android ``` 如图,添加安卓平台成功,注意要 **确保输出的 Target SDK 和 Compile SDK 版本一致**: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/vlFooBWv0zxR8sFy.webp) 如果不一致,可能会影响 APP 的运行。可以修改 `config.xml` 的 targetSdkVersion 来修改版本号: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/PVv5ud67yysriIrj.webp) ### 添加插件 由于我的项目需要调用摄像头,所以要添加对应的插件,执行下列命令: ```bash cordova plugin add cordova-plugin-camera ``` 添加插件成功: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/YDj1zN8L2oU0b6Wo.webp) ### 打包运行安卓 APP #### 打包 安装完插件后,执行 `cordova build` 命令可以打包 Android apk: ```bash cordova build android ``` 看到下列信息表示打包成功: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/tzs0auCYoOwt53LS.webp) 得到 apk 包后,有 2 种运行方式: #### 手机运行 可以直接将 apk 包发送到手机安装运行: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/HXKmxlsRF8EaF4Dn.webp) 运行效果如图: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/7Pscv21lRGtzjrFc.webp) ![](https://pic.code-nav.cn/post_picture/1601072287388278786/2IyKJy8Lh1wbhkdC.webp) #### 电脑运行 先打开 Android Studio 并启动安卓虚拟设备,然后执行 `cordova run` 命令: ```bash cordova run android ``` 就可以将 apk 安装到虚拟设备中,并且运行 APP 了,效果如图: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/8548RhgfI7Sv4Zvv.webp) ### 常见报错 打包运行是最容易遇到报错的地方,可能会遇到很多种报错,比如缺少插件、缺少文件、无法安装依赖、无法运行等等,建议直接把报错信息发给 AI,让它帮你解决。 下面鱼皮分享一些自己遇到的坑点。 #### 1、项目缺少文件 比如鱼皮的项目缺少了图标文件: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/P0FGXfw2XszdRTxE.webp) AI 尝试帮我创建图标: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/zElmwSTmtJmQqhyN.webp) 或者简单粗暴,移除配置文件中对图标的引用: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/4oSGERpl6pIhlmhe.webp) #### 2、缺少环境变量 如果环境搭建不顺利,可能会遇到下列报错,根据报错信息去进行对应的配置即可: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/HVaoJwUb3jtJ1yHN.webp) #### 3、命令执行失败 执行 `cordova run` 报错命令执行失败,可能是因为没有配置 `cmdline-tools` 到环境变量 Path 中。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/wp9CXROUx4qjOQt5.webp) #### 4、Gradle 无法安装 明明已经安装了 Gradle,但是 Cordova 仍然会安装 Gradle,而且可能因为网络原因下载失败: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/rs41w7ECVUMs57sR.webp) 这时,我们可以配置环境变量 `CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL`,指定从本地下载 Gradle。环境变量的值设置为我们自己下载的 Gradle 压缩包的路径。 ![](https://pic.code-nav.cn/post_picture/1601072287388278786/H6BtW3Mbzgdc5EPd.webp) 如果修改配置后再次执行打包命令还是报错,建议删除项目内的 `platforms/android/.gradle` 缓存,然后重试。 ## 四、已有项目打包为 APP 刚刚实战了直接用 AI 生成 Cordova APP 项目的方式,如果我们已经有现成的网站项目,也能够很方便地打包为 APP。 比如现在鱼皮有一个消消乐网页游戏项目,让我们来包装为 APP: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/AJNVvdQPUoj0abVK.webp) 1)先创建 cordova 项目: ```bash cordova create yu-game-web-app ``` 2)把已有的网页文件复制到 www 目录下: ![](https://pic.code-nav.cn/post_picture/1601072287388278786/LUqQLZ2IQKHpSE4u.webp) 3)执行 cordova 命令添加 Android 平台: ```bash cordova platform add android ``` 4)最后,打包或者直接运行: ```bash cordova run android ``` 运行成功的效果如图,还是很 nice 的~ ![](https://pic.code-nav.cn/post_picture/1601072287388278786/cAtGFfera9ulYiyk.webp) ## 最后 OK,教程到这里就结束了,由于缺少设备等原因,IOS 就先不给大家演示了。 最后给大家一些建议,Cordova 比较适合中小型网站项目,尤其适合已经有网站项目想快速转为 APP 的场景;但如果你需要搞一个复杂的大项目,依赖很多移动设备的原生能力,使用 Cordova 就不是很合适了,不如 Flutter。尤其是没有编程能力的同学来说,建议不要直接用 AI 生成复杂的 Cordova APP,很可能出现你搞不定的代码问题,但是做些小游戏、小工具还是很不错的。也希望我的分享对大家有帮助吧,想获取更多编程和 AI 干货的朋友记得关注鱼皮哦,拜拜~ ## 更多 💻 编程学习交流:[编程导航](https://www.codefather.cn/) 📃 简历快速制作:[老鱼简历](https://laoyujianli.com) ✏️ 面试刷题神器:[面试鸭](https://mianshiya.com) 📖 AI 学习指南:[AI 知识库](https://ai.codefather.cn/)

下载 APP