以下面试题覆盖了Jetpack核心组件的原理、优化及实际应用场景,适合中高级Android开发者面试准备。
1. Navigation组件的核心优势是什么?如何解决Fragment页面重叠问题?
Navigation组件通过导航图可视化管理Fragment跳转,优势包括:
- 类型安全的参数传递(SafeArgs插件)
- 自动处理返回栈,避免传统
FragmentTransaction的混乱。
解决页面重叠:确保转场动画使用setEnterAnimations,并通过NavController.clearBackStack()清理无效栈。
2. ViewModel如何实现配置更改后数据不丢失?源码层如何设计?
ViewModel通过ViewModelStore(由HolderFragment持有)在Activity重建时保留数据。源码中:
Activity#onRetainNonConfigurationInstance()保存ViewModelStoreHolderFragment通过getViewModelStore()恢复数据。
3. LiveData的“粘性事件”是什么?如何避免?
粘性事件指新Observer注册时收到最后一次数据(mVersion计数触发)。解决方案:
- 使用
SingleLiveEvent封装,通过AtomicBoolean标记消费状态。 - 或改用Kotlin Flow替代。
4. Room数据库如何优化多表查询性能?
- 使用
@Transaction包裹多表操作,避免数据不一致。 - 异步查询:返回
Flow<List<T>>或suspend函数(协程)。 - 索引优化:对高频查询字段添加
@Index。
5. WorkManager与JobScheduler/AlarmManager的区别?如何实现任务链?
-
区别:WorkManager兼容API 14+,内部按系统版本选择
JobScheduler或AlarmManager,支持约束条件(如网络状态)。 -
任务链:通过
WorkContinuation串联OneTimeWorkRequest,例如:WorkManager.getInstance() .beginWith(workA) .then(workB) .enqueue()
6. DataBinding如何避免内存泄漏?表达式优化有哪些技巧?
-
内存泄漏:在
onDestroy中调用binding.unbind()。 -
表达式优化:
- 使用
@BindingAdapter替换复杂逻辑(如Glide加载图片) - 避免在XML中写计算逻辑,改用静态方法。
- 使用
7. Paging 3.0如何实现预加载?与RecyclerView如何配合?
- 预加载:通过
PagingConfig设置prefetchDistance(如提前加载20项)。 - 配合RecyclerView:使用
PagingDataAdapter,内部自动处理分页和DiffUtil。
8. Hilt依赖注入相比Dagger2有哪些简化?
- 自动生成组件(如
@AndroidEntryPoint替代@Component) - 内置ViewModel注入:
@HiltViewModel - 减少模板代码:无需手动编写
Module和Component。
9. Compose重组优化的四大法则是什么?
- 层级扁平化:减少嵌套布局的
Modifier链(每层增加0.8ms测量耗时) - 状态隔离:用
@Stable标记不可变数据类 - 延迟加载:
LazyLayout预加载机制 - 智能缓存:
rememberSaveable保存状态。
10. 如何设计跨进程的LiveData事件总线?
结合MMKV或ContentProvider实现跨进程通信:
class ProcessAwareLiveData(private val mmkv: MMKV) : LiveData<T>() {
override fun onActive() {
mmkv.registerOnSharedPreferenceChangeListener { _, key ->
postValue(mmkv.decode(key))
}
}
}
注意:需处理多进程写入的线程同步问题(如分段锁)。