小米资深Android面经:组件化架构设计、WorkManager的原理、PMS包管理服务的工作原理

35 阅读4分钟

小米资深Android面试:小米Android开发覆盖MIUI系统定制、IoT设备互联。技术栈偏底层,面试官喜欢问系统级原理和性能数据。技术方向偏向MIUI定制、IoT互联。特色专项包括MIUI系统定制与IoT设备开发。今天8道题覆盖小米资深Android面试核心考点。

Q1:组件化架构设计和模块间通信?

组件化核心:业务模块独立编译运行,通过路由+接口通信。分层:app壳(集成+Application)→业务层(lib_user/lib_order)→基础层(lib_common/lib_network)。同层模块不直接依赖——通过ARouter路由跳转,通过服务暴露(ServiceLoader/SPI)实现模块间调用。Gradle用implementation隔离依赖,api暴露给上层。

@Route(path = "/user/detail")
class UserDetailActivity : BaseActivity() { ... }
ARouter.getInstance().build("/user/detail")
    .withString("userId", "123").navigation()

追问:组件化和插件化的区别?组件化是编译期集成(最终一个APK,模块可独立编译调试),插件化是运行时加载(多个APK,动态下发)。

Q2:WorkManager的原理和任务调度?

WorkManager是Jetpack持久化后台任务框架。核心:1)Worker定义任务(doWork在后台执行);2)Constraints约束(网络/充电/空闲);3)WorkRequest——OneTimeWorkRequest(单次)或PeriodicWorkRequest(周期最短15分钟);4)WorkManager.enqueue()提交后持久化到Room数据库——App重启或重启手机后自动恢复执行。底层根据API版本选择JobScheduler(21+)/AlarmManager+BroadcastReceiver。

val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.UNMETERED)
    .setRequiresCharging(true).build()
val work = OneTimeWorkRequestBuilder<SyncWorker>()
    .setConstraints(constraints)
    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
    .build()
WorkManager.getInstance(ctx).enqueue(work)

追问:WorkManager和JobScheduler的关系?WorkManager是上层封装——API 23+用JobScheduler,以下用AlarmManager+Receiver。开发者只用WorkManager API不用关心版本。

Q3:PMS包管理服务的工作原理?

PMS负责管理所有已安装的APK信息。APK安装时解析AndroidManifest.xml提取四大组件和权限信息,存到/data/system/packages.xml。查询时根据Intent的action/category/data匹配组件。加载过程:扫描/system/framework→/system/app→/data/app→解析→写入缓存。

追问:APK安装的完整流程?copyPackage到/data/app→dexopt(ART AOT/JIT编译)→提取so库→写packages.xml→发PACKAGE_ADDED广播。

Q4:ANR产生原因和排查方法?

ANR本质:主线程5秒内没响应输入事件,或10秒内没执行完BroadcastReceiver。排查:1)adb pull /data/anr/traces.txt看主线程调用栈;2)检查主线程是否在等锁(blocked)、做Binder调用(blocked)、I/O等待(native)、或死循环;3)线上用Watchdog机制定时post消息到主线程,超时未执行则dump堆栈上报。

# 获取完整ANR信息
adb pull /data/anr/traces.txt
adb bugreport bugreport.zip

追问:线上ANR怎么监控?FileObserver监听/data/anr/traces.txt变化 + Watchdog定时检测主线程响应。

Q5:依赖注入(Hilt/Dagger)的原理?

依赖注入解决的核心问题:对象不自己创建依赖,而是由外部注入。Hilt基于Dagger,通过注解处理器(APT)在编译期生成依赖注入的工厂代码。@Inject标注构造(提供依赖)+@Module/@Provides(提供无法直接构造的依赖如Retrofit实例)+@Component/@Subcomponent(管理依赖图和生命周期)。

@HiltAndroidApp
class MyApp : Application()
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var repository: UserRepository
}
@Module @InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides @Singleton
    fun provideRetrofit(): Retrofit = Retrofit.Builder()...build()
}

追问:Hilt和Koin的区别?Hilt编译期(注解处理器生成代码),性能好但编译慢;Koin运行时(DSL注册),简单灵活但有运行时开销。

Q6:ConstraintLayout的原理和优势?

ConstraintLayout通过约束(Constraint)定位子View——类似iOS的AutoLayout。优势:1)扁平层级——用约束替代多层嵌套的LinearLayout/RelativeLayout,减少measure/layout次数;2)Bias——控制两个约束间的比例(如水平偏左30%);3)Chain——多个View链式分布(spread/spread_inside/packed);4)Barrier/Guideline——辅助定位。ConstraintLayout 2.0还支持MotionLayout做动画。

<androidx.constraintlayout.widget.ConstraintLayout>
    <Button android:id="@+id/btn"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0.3" />
</androidx.constraintlayout.widget.ConstraintLayout>

追问:ConstraintLayout一定能减少层级吗?不一定——如果原来只有一层LinearLayout,换成ConstraintLayout反而增加了解析约束的开销。嵌套深时才值得。

Q7:Choreographer和VSync的协作?

每16.6ms(60Hz屏幕)硬件产生一个VSync信号。Choreographer收到VSync后按序执行三类回调:CALLBACK_INPUT(输入事件)→CALLBACK_ANIMATION(动画)→CALLBACK_TRAVERSAL(布局和绘制)。一帧内做不完就掉帧。

下一篇进入小米架构师——状态管理方案选型、全局异常处理、组件化路由框架设计要点。

觉得有用的同学扣1,你面试被追问最狠的是哪道题?

本系列连载中,关注不迷路,下一篇:小米架构师面经:状态管理方案选型、全局异常处理、组件化路由框架设计要点

系列简介:Android大厂面经连载,覆盖字节跳动、腾讯、阿里、美团等40+企业,从初级到架构师全岗位覆盖。每篇文章包含真实面试题+详细答案+代码示例,帮你拿到大厂Offer。