【Android面试】打包 & 启动专题

2024最新Android知识体系总结(全方面覆盖Android知识结构,面试&进阶) Android组件内核篇Activity与调用栈Fragment的管理与内核Service 内核原理组件间通信方案数据持久化篇Android文件系统轻量级Kv持久化嵌入式Sqlite数据库设计思想与代码优化篇数据结构算法设计模式六大原则程序性能优化篇OOM问题原理解析ANR问题解析Crash监控方案启动速度与执行效率优化项目实战布局检测与优化内存优化耗电优化网络传输与数据存储优化APK大小优化屏幕适配开发效率优化篇。 阅读详情

文章目录

一、安卓打包流程专题

【Android打包】打包流程
在这里插入图片描述

1. 简述从源码到最终APK生成的完整打包流程,涉及哪些关键工具链,各阶段的输入输出是什么?**

  • 标准答案:

安卓APK打包是一套标准化的编译构建流程,整体分为资源编译、源码编译、字节码转换、打包、签名、对齐这几个核心阶段。

  • 第一步,资源编译:通过aapt2编译res目录下的资源文件,生成编译后的二进制资源、资源索引表,同时生成R文件,把资源ID映射到代码中,assets资源直接复制不编译。
  • 第二步,源码编译:用javac编译器,把Java/Kotlin源码以及R文件、依赖库编译成Class字节码文件。
  • 第三步,字节码转换:通过D8/R8工具,将Class文件转换成DEX文件,同时处理类压缩、方法数超限问题,多DEX分包也在这一阶段处理。
  • 第四步,打包生成未签名APK:把二进制资源、DEX文件、so库、assets文件等,打包成一个未签名的压缩包,也就是初始APK。
  • 第五步,APK签名:对APK进行V1/V2/V3签名,校验包完整性、防止篡改,保证包来源可信。
  • 第六步,对齐优化:通过zipalign工具,对APK内部文件进行4字节对齐,减少运行时内存占用,加快读取速度。

核心工具链:aapt2(资源编译)、javac(源码编译)、D8/R8(DEX转换+混淆)、apksigner(签名)、zipalign(对齐)。

  • 速记思路:

资源编译→源码转Class→Class转DEX→打包→签名→对齐,记清六步和对应工具。

2. aapt2相比传统aapt在资源编译上有哪些改进?资源的编译、链接、打包具体是如何进行的?

  • 标准答案:
    aapt2是谷歌推出的新一代资源编译工具,拆分了编译和链接流程,相比老版aapt,核心改进有三点。第一,支持增量编译,只编译修改过的资源,大幅提升增量构建速度,老版aapt是全量编译,效率低下。第二,修复了大量资源合并冲突、命名冲突问题,兼容性更强。第三,资源编译更严格,能提前暴露资源错误,减少运行时异常。
    资源编译环节:单独编译每一个资源文件,生成二进制资源文件和中间产物,不会合并资源。链接环节:把所有编译后的二进制资源、库文件资源合并在一起,生成最终的资源索引表和完整资源包,再对接源码编译环节。
  • 速记思路:
    增量编译、拆分编译链接、报错更严格,两步走:先编译单个资源,再统一链接。

3. R.java/ResourceTable是如何生成的?在代码中引用资源ID的原理是什么?

  • 标准答案:
    R文件由aapt2在资源编译阶段自动生成,属于自动生成的常量类。系统会给res目录下每一个资源(布局、图片、字符串、颜色等)分配一个唯一的十进制常量ID,把资源名和ID一一对应,写入R类中,分为不同内部类(layout、drawable、string等)归类存放。
    在代码中引用资源,其实是引用R类里的常量ID,AMS、WMS等系统服务会通过这个ID,在资源索引表里面查找对应的二进制资源,完成加载和渲染。在Android Studio升级后,新版AS用ResourceTable替代了传统R.java,原理一致,只是存储形式更轻量化,更适配模块化开发。
  • 速记思路:
    aapt2自动生成,资源对应唯一ID,代码用ID查表找资源。

4. Java/Kotlin代码是如何被编译为Class文件,再通过D8/R8转换为DEX文件的?多DEX分包在哪个阶段处理?

  • 标准答案:

首先,Kotlin代码会通过kotlinc编译器先编译成Java代码,再和原生Java代码一起,由javac编译成Class字节码文件,这一步和普通Java项目编译一致。
随后,D8/R8工具会对所有Class文件进行处理,把Class字节码转换成安卓虚拟机支持的DEX字节码。安卓单个DEX文件有65536个方法数限制,超出后会报错。
多DEX分包在D8/R8转换阶段处理,Gradle开启multiDexEnabled之后,工具会自动把代码拆分到多个DEX文件中,打包时一起打入APK,应用启动时再加载全部DEX文件,解决方法数超限问题。

  • 速记思路:

Kotlin转Java→javac转Class→D8/R8转DEX,DEX超限,分包在D8/R8阶段处理。

5. Proguard/R8混淆的原理是什么?混淆配置文件中keep规则的作用及常见配置场景?

  • 标准答案
    混淆核心原理有三个,分别是压缩、优化、混淆。压缩是移除无用代码、无用资源、未调用的类和方法,减小包体积。优化是对字节码进行优化,简化逻辑、去除冗余代码。混淆是把类名、方法名、字段名替换成无意义的短字符(如a、b、c),防止逆向工程破解代码,同时进一步缩小包体积。
    keep规则用于保留指定类、方法、字段不被混淆和移除。常见场景:四大组件、自定义View、JNI调用的Java方法、反射用到的类、序列化实体类、第三方SDK代码,这些都必须加keep规则,否则会出现类找不到、方法调用失败等崩溃问题。
  • 速记思路
    压缩+优化+混淆,keep保留不能混淆的代码,记牢四类必保留场景。

6. APK签名(V1、V2、V3)的区别是什么?为什么Google推荐使用V2签名?V2签名对APK结构有何影响?

  • 标准答案:
    V1签名是传统Jar签名,只对APK内的单个文件签名校验,不对整个APK包校验,安全性低,修改APK内部文件后仍能通过校验,而且签名校验速度慢。
    V2签名是全包签名,在APK完整结构上增加签名区块,对整个APK内容进行校验,安全性极高,防止包被篡改、二次打包,校验速度更快,安卓7.0以上系统支持。
    V3签名在V2基础上,支持密钥轮转,更换签名密钥后仍能校验通过,适配应用更换签名的场景,兼容性更强。
    Google推荐V2签名,是因为安全性更高、校验更快,能有效防止恶意篡改。V2签名会改变APK结构,在原APK数据区和签名区之间增加专属签名块,不破坏原有文件结构。
  • 速记思路:
    V1(文件签名、不安全)→V2(全包签名、安全)→V3(支持换密钥),V2更安全是核心。

7. 简述Android App Bundle (AAB) 的打包原理,相比传统APK有什么优势?

  • 标准答案
    AAB是谷歌推出的新一代应用打包格式,替代传统APK。开发者打包生成AAB包,上传到Google Play商店,商店会根据用户设备的CPU架构、屏幕分辨率、语言等配置,自动拆分生成对应的轻量化APK,再推送给用户。
    相比传统APK,优势很明显:第一,大幅减小安装包体积,剔除设备不需要的资源和so库;第二,开发者只需打包一个AAB包,不用适配多套APK;第三,减少冗余资源,降低下载失败率,提升安装效率。
  • 速记思路
    打一个AAB包,商店按需拆分包,体积更小、适配更方便。

8. 打包过程中,assets目录与res目录的处理方式有何不同?为什么assets不会生成资源ID?

  • 标准答案
    res目录资源会由aapt2编译、索引,自动生成R文件ID,代码通过ID直接引用,系统会对资源进行优化、压缩、适配。
    assets目录资源属于原生静态资源,打包时直接复制到APK,不参与编译、不生成资源ID,不会被系统优化和筛选,保留原文件格式和路径。
    assets不生成ID,是因为它属于文件目录形式存储,适合存放大量静态文件、自定义格式文件,代码需要通过AssetManager类,用文件路径去加载,而非资源ID。
  • 速记思路
    res编译+生成ID,assets直接复制+无ID,用路径加载。

9. 什么是zipalign对齐?它在打包流程的哪个阶段执行?不执行对齐会有什么问题?

  • 标准答案:
    zipalign是APK对齐优化工具,对APK内部所有资源文件进行4字节边界对齐,让文件数据从固定偏移量开始存储。
    它在APK签名完成之后执行,属于打包最后一步优化。如果不执行对齐,系统加载APK资源时,需要额外计算偏移量,会占用更多内存,资源读取速度变慢,严重时会出现内存溢出,甚至部分系统无法正常安装应用。
  • 速记思路:
    签名后执行,4字节对齐,不对齐会卡顿、耗内存、安装失败。

10. Gradle构建脚本中,transform API的作用是什么?通常被用于哪些场景?

标准答案:transform API是Gradle提供的字节码处理接口,在Class文件转换为DEX文件之前执行,用于对Class字节码进行自定义修改、插入、删除操作。
它属于编译时插桩技术,常见场景:代码埋点统计、性能监控、日志插入、权限拦截、热修复框架、组件化路由注入等,不需要修改源码,就能在编译阶段完成代码增强。
速记思路:编译时修改字节码,用于插桩、埋点、热修复、路由注入。

11. APK由哪部分构成?

  • AndroidManifest.xml:配置文件,包含应用的基本信息,如包名、组件(Activity、Service、BroadcastReceiver等)、权限声明等。
  • classes.dex:Dalvik字节码文件,包含应用的Java/Kotlin代码编译后的可执行文件。
  • resources.arsc:编译后的资源索引文件,包含资源ID与资源值的映射。
  • res/:资源目录,包含布局文件、图片、字符串、样式等资源。
  • assets/:原始资源目录,存放应用运行时需要访问的原始文件(如音视频、HTML文件等)。
  • lib/:包含应用使用的本地库文件(如.so文件),按不同CPU架构分类存放。
  • META-INF/:签名信息目录,包含证书(CERT.RSA/DSA)和摘要文件(MANIFEST.MF)等。

二、点击APP图标到启动全流程专题

【Android Activity启动流程】启动流程深入理解
在这里插入图片描述

1. 详细描述从点击桌面Launcher图标到MainActivity的onResume执行完成的全过程,重点阐述交互逻辑。**

标准答案:

  • 第一步,用户点击桌面图标,Launcher作为系统桌面应用,会发出一个隐式Intent,包含启动入口Activity的action和category信息。
  • 第二步,Intent通过Binder跨进程通信,传递给系统核心服务AMS(ActivityManagerService),AMS负责Activity的生命周期调度和进程管理。
  • 第三步,AMS先通过PMS(PackageManagerService)校验APP是否存在、入口Activity是否配置,随后检查应用进程是否存在。
  • 第四步,如果进程不存在,AMS请求Zygote进程,孵化出应用独立进程,Zygote是所有应用进程的父进程,负责复制虚拟机和系统资源。
  • 第五步,应用进程启动后,执行ActivityThread的main方法,初始化主线程、Looper、Application,调用Application的onCreate方法。
  • 第六步,ActivityThread通过Binder向AMS汇报进程启动完成,AMS下发生命周期调度指令,依次执行入口Activity的onCreate、onStart、onResume方法。
  • 第七步,onResume执行后,WMS(WindowManagerService)创建Window并绘制界面,应用正式显示。
    速记思路:
    点击图标→Launcher发Intent→AMS校验→Zygote孵化进程→初始化Application→Activity生命周期→界面显示。

2. 冷启动场景下,系统是如何通过Zygote孵化出新进程的?ActivityThread.main()是应用进程入口吗?**

  • 标准答案:
    冷启动时应用进程未创建,AMS通过Socket通信,向Zygote进程发送创建请求。
    Zygote采用fork机制,复制自身进程空间,生成新的应用子进程,继承虚拟机环境、系统库、基础资源,不用重新初始化,提升启动速度。
    ActivityThread的main方法,是应用进程的Java层入口,属于主线程入口。进程启动后,系统会反射调用main方法,内部初始化主线程Looper,开启消息循环,同时绑定Application,完成进程初始化,是应用代码执行的起点。
  • 速记思路:
    AMS请求→Zygote fork进程,main方法是Java层入口,初始化Looper。

3. 应用进程启动后,ActivityThread如何与AMS双向通信?Application的onCreate在哪个时机调用?

  • 标准答案:
    ActivityThread和AMS通过Binder机制实现双向通信。AMS持有应用进程的Binder代理(IApplicationThread),用于下发生命周期、进程调度指令;应用进程持有AMS的Binder代理,用于向AMS汇报状态、请求系统服务。
    Application的onCreate调用时机:进程fork完成、主线程初始化完毕、Binder通信建立之后,Activity生命周期开始之前。这是应用代码最早执行的回调,用于全局初始化、SDK配置。
  • 速记思路:
    Binder双向通信,AMS发指令,App回状态,onCreate在Activity启动前。

4. 冷启动、热启动、温启动的定义及区别,生命周期回调有何不同? **

标准答案:

  • 冷启动:应用进程完全销毁,点击图标重新启动,流程最全,耗时最长。会走进程创建、Application初始化、Activity全生命周期(onCreate→onStart→onResume)。
  • 热启动:应用进程存活,Activity在后台,只是退到后台,点击图标回到前台。不会重建进程和Application,Activity不会走onCreate,只执行onRestart→onStart→onResume。
  • 温启动:介于两者之间,进程存活,但Activity被系统回收。点击启动时,不会重建进程,会重新创建Activity,执行onCreate→onStart→onResume。

速记思路:

  • 冷启动(全重来)、热启动(只恢复)、温启动(重建页面),记清生命周期差异。

5. 应用启动白屏/黑屏的原因是什么?如何优化启动速度?

标准答案:

  • 白屏/黑屏产生原因:启动时,系统会先加载应用清单文件里的主题背景,默认主题是黑色或白色,此时Application和Activity还没初始化,界面未绘制,就会出现空白窗口。
  • 启动优化方向:第一,减少Application onCreate里的耗时操作,同步操作改异步,非核心初始化懒加载;第二,设置启动页背景,替换默认白屏,提升视觉体验;第三,优化布局层级,减少onCreate里的耗时操作;第四,避免启动时IO操作、网络请求、大量GC;第五,合理使用多线程,拆分初始化任务。

速记思路:

  • 空白窗口导致黑屏白屏,优化:懒加载、异步、换启动背景、减耗时。

6. 系统内存不足时,点击图标重启应用,和正常冷启动有何差异?

  • 标准答案:
    正常冷启动是用户手动杀死进程,或进程完全销毁,启动流程完整,数据完全重置。内存不足触发的启动,属于系统强制回收进程,应用会保存临时状态和页面栈。
    差异点:第一,系统会尝试恢复之前的Activity栈,而不是直接启动入口Activity;第二,会触发Activity的状态恢复逻辑,执行onRestoreInstanceState;第三,Application不会重复初始化;第四,可能出现数据丢失、页面恢复异常,需要做好状态保存和容错处理。
  • 速记思路:
    正常冷启动全重置,内存不足重启会恢复页面栈、保存状态。

7. Intent在应用启动流程中的传递路径?隐式Intent如何匹配到目标Activity?

  • 标准答案:

传递路径:用户点击图标→Launcher生成Intent→Launcher进程跨进程传给AMS→AMS校验Intent→AMS分发到应用进程→Activity接收Intent。
隐式Intent匹配逻辑:AMS通过PMS,扫描所有已安装应用的清单文件,匹配Intent里的action、category、data,找到注册了对应过滤规则的Activity,确认唯一目标组件,再完成跳转。如果匹配到多个,会弹出选择框。

  • 速记思路:
    Launcher→AMS→应用进程,PMS匹配清单过滤规则找到页面。

8. AMS如何调度Activity生命周期(onCreate→onStart→onResume)

  • 标准答案:
    AMS作为系统服务,统一管理所有应用的Activity生命周期,通过Binder指令控制。
    进程启动完成后,AMS先判断Activity状态,处于未创建状态,先下发onCreate指令,完成页面初始化、布局加载。
    onCreate执行完毕,AMS下发onStart指令,页面变为可见状态,但无法交互。随后下发onResume指令,页面获取焦点,可响应触摸事件,彻底显示。
    整个流程由AMS主动调度,ActivityThread接收指令,反射调用对应的生命周期方法,保证生命周期执行顺序严格有序。
  • 速记思路:
    AMS发指令,ActivityThread执行,按create→start→resume顺序执行。

9. 应用启动时,Window如何被创建并显示?WMS扮演什么角色?

  • Activity 启动请求
    应用通过调用 startActivity() 发起启动请求,系统会通过 ActivityManagerService(AMS) 来处理这个请求,并启动目标 Activity。
  • 创建 PhoneWindow 和 DecorView
    当目标 Activity 被创建时,系统会为其创建一个 PhoneWindow 实例(Window 的具体实现类),并通过 setContentView() 设置布局内容,最终生成 DecorView,也就是整个界面的根视图。
  • ViewRootImpl 初始化并连接 WMS
    在 ActivityThread 执行 handleResumeActivity() 时,会通过 WindowManager 将 DecorView 添加到系统中。这时会创建 ViewRootImpl,它是连接 View 层与 WMS 的核心类。
  • WMS 接收添加窗口请求
    WMS 会为这个窗口分配唯一的 token,确定窗口层级(Z-order),并进行布局计算。同时,WMS 会与 SurfaceFlinger 通信,为窗口分配一块绘图的 Surface。
  • 执行测量、布局与绘制流程
    ViewRootImpl 会触发 performTraversals(),依次执行 measure、layout、draw 流程,将 UI 内容绘制到 Surface 上。
  • 最终显示在屏幕上
    SurfaceFlinger 负责将所有窗口的图形缓冲区进行合成,并送显到屏幕上,最终用户可以看到应用界面。

10. 启动优化中异步初始化和懒加载的含义,分别优化哪个阶段耗时?

  • 标准答案:
    异步初始化:把Application和Activity onCreate里的同步耗时操作,放到子线程执行,不阻塞主线程,不影响生命周期执行,优化主线程阻塞时间,加快页面显示。主要优化进程初始化、Application onCreate阶段的耗时。
    懒加载:核心是延迟加载,非核心资源、非立即显示的数据、页面,推迟到页面显示后、用户交互时再加载,不占用启动时段资源。主要优化Activity onCreate、onResume阶段的耗时,减少启动时的工作量,缩短启动时间。
  • 速记思路:
    异步(子线程做耗时,不卡主线程),懒加载(延后加载,不抢启动时间)。

11. 深入理解Instrumentation、ActivityThread、ActivityManagerService 三者之间的协作关系 ***

可以参考前面的流程图

  • 组件职责简介:
    ActivityManagerService(AMS)
    系统级服务,运行在 System Server 进程中。
    负责管理四大组件的生命周期、任务栈管理、进程调度等。
    接收来自应用端的启动请求,并决定目标 Activity 的启动时机与方式。
    ActivityThread
    应用的主线程,是应用进程的入口。
    内部通过 H(Handler)处理来自 AMS 的消息,如 LAUNCH_ACTIVITY、PAUSE_ACTIVITY 等。
    负责调用 performLaunchActivity() 启动 Activity。
    Instrumentation
    用于监控 Activity 的生命周期和系统交互,支持单元测试。
    一个应用进程中通常只有一个 Instrumentation 实例
    提供 newActivity()、callActivityOnCreate() 等方法,用于创建和管理 Activity 实例。
    在 Activity 启动过程中,真正调用其生命周期方法。

  • 启动流程中的协作关系:

  • AMS 接收启动请求
    应用调用 startActivity() 后,会通过 Binder 调用到 AMS 的 startActivity() 方法。

  • AMS 决定启动目标 Activity
    AMS 会检查目标 Activity 的状态、任务栈、权限等信息,并决定是否需要新建进程或复用已有进程。

  • AMS 向目标进程发送 LAUNCH_ACTIVITY 消息
    如果目标进程已启动,则 AMS 通过 Binder 向该进程的 ActivityThread 发送 LAUNCH_ACTIVITY 消息。

  • ActivityThread 处理消息并调用 Instrumentation
    ActivityThread 中的 H 接收到消息后,调用 handleLaunchActivity(),进而调用 Instrumentation.newActivity() 创建 Activity 实例。

  • Instrumentation 调用生命周期方法
    Instrumentation 会调用 callActivityOnCreate()、callActivityOnStart()、callActivityOnResume() 等方法,完成 Activity 的生命周期初始化。

  • 最终完成显示
    在 onResume() 中,会执行 Activity.makeVisible(),触发 ViewRootImpl 的创建,最终完成窗口的显示。

  • 总结:
    AMS 是“指挥官”:负责全局调度,决定何时启动哪个 Activity。
    ActivityThread 是“执行者”:接收 AMS 指令,调度执行具体操作。
    Instrumentation 是“代理”:负责实际创建 Activity 实例并调用其生命周期方法。

三、安卓系统启动流程专题

【Android FrameWork】系统启动流程
在这里插入图片描述

1. 简述安卓设备从按下电源键到Launcher桌面显示的完整系统启动流程。**

  • 标准答案:
    开机自检:按下电源键,设备执行BootROM引导,加载BootLoader程序,初始化硬件,启动Linux内核。
    内核启动:Linux内核加载完成,初始化进程管理器、内存管理、驱动程序,启动第一个用户进程init进程。
    init进程启动:解析init.rc脚本,创建系统目录,启动各类系统守护进程,孵化Zygote进程。
    Zygote进程启动:初始化Java虚拟机,注册系统服务,预加载系统资源和类,监听AMS请求,等待孵化应用进程。
    SystemServer进程启动:Zygote fork出SystemServer,这是系统核心服务进程,启动AMS、WMS、PMS等核心服务。
    启动桌面:系统服务初始化完毕,SystemServer启动Launcher桌面应用,设备开机完成,显示桌面。
  • 速记思路:
    开机→内核→init→Zygote→SystemServer→核心服务→Launcher

2. Linux内核启动后,第一个用户进程是什么?作用是什么?**

标准答案:
Linux内核启动后,第一个用户进程是init进程,进程号为1,是所有用户进程的祖进程。
核心作用:初始化系统环境,解析启动脚本,创建系统文件夹,加载硬件驱动,启动系统守护进程,fork孵化Zygote进程,管控系统进程的创建和销毁,保证系统基础运行环境。
速记思路:
init是1号进程,初始化系统,孵化Zygote

3. Zygote进程如何被启动?与SystemServer进程的关系是什么?**

  • 标准答案:
    Zygote进程由init进程,通过解析init.rc脚本启动,属于系统级核心进程。Zygote是所有应用进程的父进程,采用fork机制创建应用子进程。
    SystemServer进程由Zygote进程fork生成,是系统最重要的服务进程,负责启动和管理所有系统服务。两者是父子进程关系,Zygote负责孵化应用进程,SystemServer负责运行系统服务。
  • 速记思路:
    init启动Zygote,Zygote fork出SystemServer(不止这一个进程),父子进程。

4. SystemServer进程启动后,会初始化哪些核心系统服务?

  • 标准答案:
    SystemServer启动后,会初始化一系列系统核心服务,高频核心服务有:AMS(ActivityManagerService,管理四大组件生命周期、进程调度)、WMS(WindowManagerService,窗口管理、界面显示)、PMS(PackageManagerService,应用安装、卸载、包信息管理)。
    除此之外,还有IMS(输入管理服务)、电池管理服务、网络管理服务、通知管理服务等,共同支撑整个安卓系统运行。
  • 速记思路:
    核心三大服务:AMS、WMS、PMS,再补充其他辅助服务。

5. 简述PMS在系统启动阶段的主要工作。

标准答案:
PMS是包管理服务,系统启动阶段核心工作:
第一,扫描系统目录、应用安装目录,解析所有APK的清单文件;
第二,解析应用权限、四大组件、版本信息,缓存包信息;
第三,完成应用安装、注册、权限校验;
第四,对外提供包查询、组件匹配能力,供AMS等服务调用。
速记思路:
扫描APK→解析清单→缓存信息→管理包和权限。

附录1: R8的理解

一、如何开启R8

一句话:在module的build.gradle(app模块),设置 minifyEnabled true,就自动启用R8;minifyEnabled false 用D8。
android {
buildTypes {
release {
minifyEnabled true // 开启R8
proguardFiles getDefaultProguardFile(‘proguard-android-optimize.txt’), ‘proguard-rules.pro’
}
}
}
补充:AGP 3.4+ 默认R8,不需要额外开关。
proguardFiles 指定混淆规则文件,语法和旧Proguard基本兼容。
二、核心注意事项(面试重点)

  1. 反射用到的类、方法、字段,需要 -keep 保留
    R8静态代码分析,找不到直接调用就摇树删除代码,反射调用会出现类找不到、方法找不到崩溃。

• 框架类(Gson、Retrofit、Room)官方一般自带proguard规则;

• 自己写的反射实体类,手动写 -keep 规则。

  1. 混淆会重命名类名、方法名
    如果业务依赖类名字符串、序列化(Gson序列化实体),不keep的话,字段名被改成a/b/c,解析JSON直接失败。
    示例规则:
    -keep class com.xxx.bean.**{*;}

  2. 不要随便关闭优化
    proguard-android-optimize.txt 是带优化的规则;还有 proguard-android.txt 关闭部分优化。优先用optimize版本,缩减效果更好。

  3. R8优化会做方法内联、代码合并
    栈轨迹(崩溃堆栈)的类/方法会被内联,崩溃日志看不懂。需要保留mapping文件,打包输出mapping.txt,上传到平台做堆栈还原。
    注意:mapping文件每次打包都会变,需要妥善保存。

  4. 多Dex场景配合R8
    R8摇树会删除无效代码,优先用R8减少方法数,而不是直接上multiDex,减少多dex带来的启动开销。如果方法数依然超标,再开启multiDexEnabled true。

  5. 资源压缩 shrinkResources
    常和R8一起开启,删除未使用资源。
    shrinkResources true
    ⚠️ 坑:代码动态引用资源(R.id."xxx"字符串获取资源),R8资源压缩识别不到,会把资源删掉。要用tools:keep在xml保留资源。

  6. Debug包不要开minifyEnabled
    Debug开启minify编译很慢,断点调试困难,调试信息被移除。只在Release打开。

  7. 第三方SDK的混淆规则
    很多SDK文档会提供对应的proguard规则,需要加到proguard-rules.pro,否则SDK内部类被混淆导致功能异常。

高频追问

问:R8开启后,打包输出什么文件?
答:输出dex文件,同时输出mapping.txt,记录原始名称和混淆后的名称映射,用于还原崩溃堆栈。

问:-dontwarn是干嘛的?
答:忽略找不到引用的警告,只是屏蔽警告,不会保留类;真正需要保留代码还是要写-keep。

背诵精简版

开启:release构建块中设置minifyEnabled true,AGP3.4+自动启用R8,搭配proguard混淆规则文件。
注意事项:

  1. 反射、序列化类用-keep保留,防止摇树删除;

  2. 保存mapping.txt,用于还原混淆后的崩溃堆栈;

  3. shrinkResources资源压缩和R8搭配使用,动态引用资源需要tools:keep;

  4. 优先R8摇树减少方法数,解决65536问题,不得已再开multidex;

  5. 第三方SDK添加官方给的混淆规则;Debug不要开启minify。

2020最新Android知识体系总结(全方面覆盖Android知识结构,面试&进阶) 前言 想要成为一名优秀的Android开发,你需要一份完备的 知识体系,在这里,让我们一起成长为自己所想的那样~。 此篇文章是初中高级工程师学习文章,知识体系较为完整。有如下特点: [1]知识结构全面 [2]跟随当下技术潮流实时更新 [3]可用于面试 & 学习 [4]知识分为文字部分和视频部分,任性选择 [5]正确的职业规划 [6]方便工作过程中遗忘知识点快速查询 知识体系 这份知识体系大纲包括: Java部分: 深入Java泛型篇 泛型的作用与定义 通配符与嵌套 泛型上下边界 阅读详情

相关推荐

2024年Android最新知识体系最强总结(全方面覆盖Android知识结构,BAT面试&学习进阶)

我坚信,坚持学习,每天进步一点,滴水穿石,我们离成功都很近!以下是总结出来的字节经典面试题目,包含:计算机网络,Kotlin,数据结构与算法,Framework源码,微信小程序,NDK音视频开发,计算机网络等。字节高级Android经典面试题和答案。

m0_60721649的博客 1072

Android应用启动流程与APK打包学习总结

APK打包流程和应用启动流程

2301_80329517的博客 984

头条、阿里、快手、OPPO、BIGO 等最新 Android 面试真题集锦

南尘在 2019 年 7 月毫无准备的情况下也参加了几家一线互联网公司的面试,包括阿里、头条、快手、趣头条、BIGO、讯飞、OPPO,也熙熙攘攘拿了几个 offer,最终选取了其中一家公司进行入职。 每次面试后,其实也有进行面试题的一些收集和总结,确实,面试其实就是一次查漏补缺的过程。本着对公司负责的态度,这里就不说面试题来自哪家公司了。不过还是要把记录下来的这些真题分享给大家。 另外,面试题一般...

刘世麟的博客 2322

Android Studio之Gradle多渠道打包,android面试2020

友盟多渠道打包 =========== 废话不多说,以友盟统计为例,在AndroidManifest.xml里面会有这么一段: <meta-data android:name=“UMENG_CHANNEL” android:value=“Channel_ID” /> 里面的 Channel_ID 就是渠道标示。我们的目标就是在编译的时候这个值能够自动变化。 第一步 在 AndroidManifest.xml 里配置 PlaceHolder <meta-data

wa2231a的博客 504

Ansys-结构动力学分析-圆柱斜齿轮模态分析学习心得

模态分析的步骤基本一直,不同点在于选择什么单元类型,模型,节点约束等 圆柱斜齿轮模态分析的难点在于圆柱斜齿轮的模型建立,和所要约束的节点的选择。 用命令流方法建立齿轮模型效率较高,当然,在ansys里建立复杂的模型实在不敢恭维,对于自下而上建模,需要知道每个关键点的坐标位置。下图是创建圆柱斜齿轮模型的命令流方式。 模型不同使用的数据也就不同了。 对于施加约束的问题这就必须要熟悉select e...

weixin_45385183的博客 1831

PD虚拟机安装CentOS7后必做的Parallels Tools配置指南(附常见错误解决)

本文详细指导在Mac的Parallels Desktop虚拟机中安装CentOS 7后如何高效配置Parallels Tools,包括环境准备、镜像挂载、依赖问题解决及性能优化。特别针对常见错误如挂载失败、依赖缺失等提供实用解决方案,帮助用户实现主机与虚拟机间的无缝交互和显示优化。

weixin_29288313的博客 301

Android四种启动模式LanchMode(1),2024年Android阿里&腾讯&百度&字节校招面试汇总

每一个移动开发者都在为 Flutter 带来的“快速开发、富有表现力和灵活的 UI、原生性能”的特色和理念而痴狂,从超级 App 到独立应用,从纯 Flutter 到混合栈,开发者们在不同的场景下乐此不疲的探索和应用着 Flutter 技术,也在面临着各种各样不同的挑战。只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

2401_84007015的博客 872

Silvaco TCAD 2018安装后,如何配置TonyPlot 5.0.22.R并解决绘图报错?

本文详细介绍了在Windows系统上安装Silvaco TCAD 2018后,如何正确配置TonyPlot 5.0.22.R并解决常见的绘图报错问题。内容包括版本兼容性分析、环境变量设置、常见错误解决方案以及性能优化建议,帮助用户顺利完成仿真结果的可视化工作。

weixin_31031711的博客 420

2024年Android最全Android 118道基础面试题,面试途中不卡题(1),安卓面试简历

光有这些思路和搞懂单个知识的应用是还远远不够的,在Android开源框架设计思想中的知识点还是比较多的,想要搞懂还得学会整理和规划:我们常见的**Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、IOC依赖注入框架、最近架构组件Jetpack等等Android第三方开源框架,**这些都是属于Android开源框架设计思想的。如下图所示:这位阿里P8大佬针对以上知识点,熬夜整理出了一本长达1042页的完整版如何解读开源框架设计思想。

2401_84545830的博客 731

Unity微信小游戏资源管理实战:YooAsset的Tag与Group策略精讲

本文深入解析了在Unity微信小游戏开发中,如何利用YooAsset的Tag与Group策略进行精细化资源管理。通过实战案例,详细阐述了如何通过Tag实现核心资源的必下与额外资源的按需加载,并借助Collector的合理打包策略,实现热更新包体最小化,从而有效解决加载慢、更新流量大的痛点,最终提升玩家体验。

weixin_29012677的博客 270

Vofa+使用笔记(1):用Vofa+通过串口连接显示波形

1. 介绍 Vofa+有三种协议设置 rawdata:你发什么就显示什么,跟普通的串口助手一样 firewater:最简单在VOFA+里绘制波形的协议,建议仅在通道数量不多、发送频率不高的时候使用。 justfloat:有一定的数据格式,此协议非常适合用在通道数量多、发送频率高的时候。 2. 使用步骤 设置号下面三个地方,使用的协议以及传输的方式 拉出控件 (最开始上位机没有识别到你的数据的时候,右边是没有数据显示的,如果你想要y轴显示什么数据,右边设置显示也可以,右键波形图然后Y轴设置也行) 把进

苏释州的博客 5万+

Android面试——2019面试心得(已获得offer)

最近出去找工作了,分享一下我在面试过程中遇到的问题,希望对Android找工作的小伙伴有帮助。 1.谈谈Android事件分发。 Android事件分发顺序是Activity->ViewGroup->View,都是在dispatchTouchEvent()方法开始调用。 2.如何设计一个图片加载库,讲一下思路 选用Glide图片加载库,使用单例模式,让应用层那边可以链式调用图片加载库,...

裕博的博客 1586

静态时序分析(Static Timing Analysis, STA):简介及内容导航

静态时序分析(简称STA)是用来验证数字设计时序的技术之一,另外一种验证时序的方法是时序仿真,时序仿真可以同时验证功能和时序。“时序分析”这个术语就是用来指代“静态时序分析“或”时序仿真“这两种方法之一,简单来说,时序分析的目的就是为了解决设计中的各种时序问题。STA被称为静态的原因是其对于设计的分析是静态地执行的,并不依赖于施加在输入端口上的激励。相比之下,时序仿真则可以被视作动态地执行对设计的分析,具体过程描述如下:施加一组激励,观察在这组激励下电路行为是否符合要求,然后换一组激。

Starry__的博客 1990

最全美团安卓面试,程序员如何自我学习和成长?先收藏了,2024年最新面试官必问的5个问题

(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总)面试成功其实是必然的,因为我做足了充分的准备工作,包括刷题啊,看一些Android核心的知识点,看一些面试的博客吸取大家面试的一些经验,

2401_84519929的博客 962

把 sy-* 带进 ABAP CDS:ABAP 7.50 里的环境信息新姿势($session 与 @Environment.systemField 实战)

摘要:ABAP 7.50在CDS视图中引入两种获取环境信息的方式:1)直接使用$session会话变量读取用户、客户端和系统语言;2)通过@Environment.systemField注解参数,由Open SQL自动注入系统字段。$session方式简单但依赖Open SQL访问路径,非ABAP环境下可能失效;注解参数方案更工程化,依赖关系明确且支持测试。建议ABAP体系内优先使用$session,对外接口采用参数化方案。两种方式各有适用场景,正确选择可避免潜在风险。(148字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 152

【WRF-Urban】使用 CGLC-MODIS-LCZ_100m 数据集运行 WRF 时的城市参数化问题

【WRF-Urban】使用 CGLC-MODIS-LCZ_100m 数据集运行 WRF 时的城市参数化问题

WW、forever的博客 710

Android开发中常见的一些问题面试专题,大牛最佳总结

码农A:看见标题我就震惊了。 码农B:我也是。 码农C:我琢磨着,UC震惊部还缺人吗?这小编是个人才啊。 某小编:标题是震惊的,但内容是朴实无华的。 前言 Android四大组件:Activity、Service、BroadcastReceiver、ContentProvider。它们的作用分别是: Activity—>配合View展示界面 Service—>长时间在后台运行不与用户直接交互 BroadcastReceiver—>接收广播 ContentProvider—>提供数据

m0_56169789的博客 223

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

2024年安卓最新面试官:今日头条启动很快,你觉得可能是做了哪些优化?,面试必背

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家这里笔者分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。【视频教程】天道酬勤,只要你想,大厂offer并不是遥不可及!

2401_84564150的博客 693

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

android面试题app,2024最新Android面试笔试

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套。

2401_84413145的博客 1167

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Android常见面试题&字节跳动、阿里、腾讯2019实习生Android岗部分面试题

原文地址:https://github.com/DmrfCoder/interview/blob/master/Android/Android常见面试题.md 文章目录什么是ANR,如何避免主线程中的Looper.loop()一直无限循环为什么不会造成ANR?ListView原理与优化ContentProvider实现原理如何使用ContentProvider进行批量操作?为什么要使用通过`Con...

ai-exception的博客 9826

Android反编译,修改apk启动页

前言 不得不说自从有了IDE之后,很多原本很基本的开发命令开发步骤似乎被人们慢慢淡忘了,特别是Android开发,先是eclipse+adt作为Android开发的IDE,到现在的Android Studio2.3.3的功能可谓是如此得强大,编译速度越来越快。然而很多基础的东西却被这强大的IDE悄悄地替我们完成了,比如apk的编译,打包,签名设计,而开发者需要做的仅仅是在GUI界面点击编译,打包按钮

宿罪的博客 1万+

安卓面试题总结

Android 的四大组件分别是:Activity、Service、Broadcast Receiver 和 Content Provider. 1)Activity:这是你与用户进行交互的入口。每一个 Activity 都是一个单独的界面,负责显示 UI和响应用户操作。 2)Service:Service 是运行在后台且不直接与用户交互的组件。适用于需要在后台执行长时间运行操作的任务,类似播放音乐或下载文件等。 3)Broadcast Receiver:用于

my_power520的博客 587

2024Android面试心得:斩获3个大厂offer后,大厂常考知识点 & 面试技巧出炉

面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

2401_83739434的博客 1138

Android知识体系总结2024(全方面覆盖Android知识结构,面试&进阶)

Android高级进阶篇UI绘制过程一个app启动过程Android 动画机制View事件分发热更新 & 插件化Handler源码分析Android优化篇内存优化布局优化UI卡顿优化UI适配优化apk安全优化Android职业方向篇【这是笔者新加入的,对于Andorid开发者而言非常重要,要有自己的职业规划】资深UI工程师[自定义控件,源码方向]Android底层开发工程师[C++音视频/图像算法/智能家居]

2401_84023314的博客 940
上一篇: 【Android面试】View绘制流程专题
下一篇: 【Android面试】ViewModel & LiveData & EventBus专题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值