深入剖析 Android 核心组件(Activity、Fragment、Service、BroadcastReceiver)生命周期 API 背后的实现原理,以及常见问题(如屏幕旋转、进程恢复)的底层机制,并结合 Android 源码(基于 AOSP)和系统机制,详细讲解生命周期的原理。
一、Activity 生命周期的底层原理
1. Activity 生命周期的实现机制
Activity 是 Android 应用的核心组件,其生命周期由 ActivityManagerService (AMS) 和 ActivityThread 共同管理。以下是生命周期的底层实现原理:
核心组件与流程
- ActivityManagerService (AMS):
- 运行在系统进程(System Server)中,负责管理所有 Activity 的生命周期、栈管理(如任务栈、进程栈)以及进程调度。
- AMS 通过 Binder IPC 与应用进程通信,调用 Activity 的生命周期方法。
- ActivityThread:
- 运行在应用进程的主线程,是应用的入口点,负责接收 AMS 的指令并调度 Activity 生命周期。
- 通过 Handler 和 Looper 机制处理 AMS 发送的消息(如启动、暂停 Activity)。
- Instrumentation:
- 是一个桥接层,负责在应用进程内调用 Activity 的具体生命周期方法(如
onCreate、onPause)。 - 提供生命周期调用的钩子,开发者可以通过自定义 Instrumentation 拦截生命周期。
- 是一个桥接层,负责在应用进程内调用 Activity 的具体生命周期方法(如
生命周期调度流程
以 onCreate 为例,剖析其调用链:
- 用户启动 Activity:
- 用户点击应用图标或通过 Intent 触发 Activity 启动。
- 系统通过 Launcher 或其他组件生成 Intent,调用
startActivity。
- AMS 接收请求:
startActivity通过 Binder 调用 AMS 的startActivity方法。- AMS 检查权限、解析 Intent、确定目标 Activity,并决定是否创建新进程或复用现有进程。
- 进程创建与 ActivityThread 初始化:
- 如果需要新进程,AMS 通过 Zygote fork 出新进程,并加载
ActivityThread。 ActivityThread的main方法初始化主线程 Looper 和 Handler。
- 如果需要新进程,AMS 通过 Zygote fork 出新进程,并加载
- Activity 实例化与生命周期调用:
ActivityThread接收 AMS 的LAUNCH_ACTIVITY消息,通过 Instrumentation 实例化 Activity(调用newActivity)。- Instrumentation 调用
Activity.performCreate->Activity.onCreate。
- UI 渲染:
onCreate中调用setContentView,触发 View 树的创建和布局,最终由 ViewRootImpl 完成绘制。
源码(简化,基于 AOSP Android 12):
// ActivityThread.java
public void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity a = performLaunchActivity(r, customIntent); // 创建并调用 onCreate
if (a != null) {
handleResumeActivity(r.token, false, r.isForward, "handleLaunchActivity");
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(cl, r.activityInfo.name, r.intent); // 实例化 Activity
if (activity != null) {
activity.attach(...); // 初始化 Context、Window 等
mInstrumentation.callActivityOnCreate(activity, r.state); // 调用 onCreate
}
} catch (Exception e) {
// 异常处理
}
return activity;
}
// Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
activity.performCreate(icicle); // 调用 Activity 的 performCreate
}
// Activity.java
final void performCreate(Bundle icicle) {
onCreate(icicle); // 开发者重写的 onCreate
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
生命周期状态机
Activity 的生命周期由 AMS 维护的状态机控制,状态包括:
- CREATED、STARTED、RESUMED、PAUSED、STOPPED、DESTROYED。
- AMS 通过
ActivityRecord(AMS 内部表示 Activity 的对象)跟踪每个 Activity 的状态,并根据用户操作(如按 Home 键、屏幕旋转)或系统事件(如进程杀死)触发状态转换。
屏幕旋转的底层原理
- 触发机制:
- 屏幕旋转导致设备配置(
Configuration)变化(如orientation、screenSize)。 - 系统通过 WindowManagerService (WMS) 检测配置变化,通知 AMS。
- AMS 默认销毁并重建 Activity,以加载新的资源(如横屏布局)。
- 屏幕旋转导致设备配置(
- 源码分析:
// ActivityStackSupervisor.java (AMS) void handleConfigurationChanged(Configuration config) { for (ActivityRecord record : mActivityRecords) { if (!record.handlesConfigChanges()) { // 检查 android:configChanges record.getTask().restartActivity(record); // 重启 Activity } } } - 为什么销毁重建:
- Android 假设配置变化需要重新加载资源(如布局、字符串),因此重建 Activity 是默认行为。
- 如果开发者声明
android:configChanges,AMS 不会销毁 Activity,而是调用onConfigurationChanged。
进程恢复的底层原理
- 进程死亡场景:
- 系统因内存压力杀死应用进程(优先级低的进程,如后台进程)。
- 用户重新打开应用,系统尝试恢复之前的 Activity 栈。
- 恢复机制:
- AMS 保存 Activity 栈状态(
TaskRecord和ActivityRecord),包括每个 Activity 的Bundle(通过onSaveInstanceState保存)。 - 恢复时,AMS 通过
ActivityThread重新创建进程,并根据保存的栈状态重建 Activity,调用onCreate并传入保存的savedInstanceState。
- AMS 保存 Activity 栈状态(
- 源码分析:
// ActivityStackSupervisor.java void restorePersistentTaskIfNeeded(TaskRecord task) { for (ActivityRecord ar : task.mActivities) { if (ar.state != null) { scheduleLaunchActivity(ar.intent, ar.state); // 恢复 Activity } } }
2. 常见问题与底层解决方案
屏幕旋转
- 问题本质: 配置变化触发 Activity 重建,
onSaveInstanceState和onCreate之间的状态传递依赖 AMS 保存的Bundle。 - 底层解决方案:
- ViewModel:
- ViewModel 存储在
ViewModelStore中,由ViewModelProvider管理。 - 配置变化时,Activity 销毁但
ViewModelStore保留(通过NonConfigurationInstances),因此 ViewModel 不丢失。 - 源码:
// ComponentActivity.java Object getLastNonConfigurationInstance() { return mViewModelStore; // 保存 ViewModelStore }
- ViewModel 存储在
- SavedStateHandle:
- 通过
SavedStateRegistry保存状态到Bundle,在进程恢复时由 AMS 恢复。 - 源码:
// SavedStateRegistry.java void performRestore(Bundle savedState) { if (savedState != null) { mRestoredState = savedState.getBundle("androidx.lifecycle.BundlableSavedStateRegistry.key"); } }
- 通过
- 自定义配置处理:
- 声明
android:configChanges后,AMS 不销毁 Activity,而是通知onConfigurationChanged。 - 开发者需手动更新资源(如重新加载布局)。
- 声明
- ViewModel:
进程恢复
- 问题本质: 进程死亡后,AMS 尝试恢复 Activity 栈,但状态依赖
onSaveInstanceState保存的Bundle,而Bundle有大小限制(通常 1MB)。 - 底层解决方案:
- 持久化存储:
- 使用 Room 数据库或 SharedPreferences 保存状态。
- Room 使用 SQLite,数据存储在文件系统中,不受
Bundle限制。 - 源码(Room 插入数据):
// RoomDatabase.java public void insert(T entity) { SQLiteDatabase db = mDatabase; db.beginTransaction(); try { mDao.insert(entity); db.setTransactionSuccessful(); } finally { db.endTransaction(); } }
- SavedStateHandle:
- 结合 ViewModel 和
SavedStateRegistry,确保状态在进程恢复时由 AMS 自动恢复。
- 结合 ViewModel 和
- 最小化 Bundle 内容:
- 仅保存必要状态(如 ID 或标志),其他数据通过数据库或网络重新加载。
- 持久化存储:
3. 代码示例(深入优化)
优化屏幕旋转和进程恢复,使用 ViewModel 和 Room:
// 数据实体
@Entity(tableName = "user_data")
data class UserData(
@PrimaryKey val id: String,
val input: String
)
// Room DAO
@Dao
interface UserDataDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(data: UserData)
@Query("SELECT * FROM user_data WHERE id = :id")
suspend fun getById(id: String): UserData?
}
// Room Database
@Database(entities = [UserData::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDataDao(): UserDataDao
}
// ViewModel
class MainViewModel(
private val savedStateHandle: SavedStateHandle,
private val userDataDao: UserDataDao
) : ViewModel() {
private val _userInput = MutableLiveData<String>()
val userInput: LiveData<String> get() = _userInput
init {
viewModelScope.launch {
val savedData = userDataDao.getById("user_1")
val input = savedStateHandle.get<String>("user_input") ?: savedData?.input
_userInput.value = input
}
}
fun saveInput(input: String) {
_userInput.value = input
savedStateHandle.set("user_input", input)
viewModelScope.launch {
userDataDao.insert(UserData("user_1", input))
}
}
}
// Activity
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val database = Room.databaseBuilder(this, AppDatabase::class.java, "app_db").build()
viewModel = ViewModelProvider(
this,
SavedStateViewModelFactory(this, MainViewModel::class.java, database.userDataDao())
).get(MainViewModel::class.java)
val editText = findViewById<EditText>(R.id.editText)
viewModel.userInput.observe(this) { input ->
editText.setText(input)
}
editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
viewModel.saveInput(s.toString())
}
// 其他方法省略
})
}
}
二、Fragment 生命周期的底层原理
1. Fragment 生命周期的实现机制
Fragment 是 Activity 的子模块,其生命周期由 FragmentManager 和 FragmentController 管理,依赖于宿主 Activity 的生命周期。
核心组件与流程
- FragmentManager:
- 负责管理 Fragment 的生命周期、事务(
FragmentTransaction)和回退栈。 - 通过
FragmentHostCallback与 Activity 交互。
- 负责管理 Fragment 的生命周期、事务(
- FragmentController:
- 协调 Fragment 和 Activity 的生命周期,确保 Fragment 状态与 Activity 同步。
- FragmentState:
- AMS 保存 Fragment 的状态(通过
onSaveInstanceState),在进程恢复时重建 Fragment。
- AMS 保存 Fragment 的状态(通过
生命周期调度流程
以 onCreateView 为例:
- Fragment 事务提交:
- 开发者调用
FragmentTransaction.add或replace,提交事务到FragmentManager。 FragmentManager将事务加入待执行队列。
- 开发者调用
- 事务执行:
FragmentManager调用execPendingActions,处理事务。- 创建 Fragment 实例,调用
performCreate->onCreate。 - 调用
performCreateView->onCreateView。
- 视图绑定:
onCreateView返回的 View 被添加到 Activity 的 View 树中。
源码(简化,基于 AOSP Android 12):
// FragmentManagerImpl.java
void moveToState(Fragment f, int newState) {
if (f.mState < newState) {
switch (f.mState) {
case Fragment.INITIALIZING:
f.performAttach();
f.performCreate(f.mSavedFragmentState);
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
f.performCreateView(f.mSavedFragmentState);
f.performViewCreated();
}
// 其他状态
}
f.mState = newState;
}
}
// Fragment.java
void performCreateView(Bundle savedInstanceState) {
mView = onCreateView(mLayoutInflater, null, savedInstanceState);
if (mView != null) {
mView.setSaveFromParentEnabled(false);
}
}
屏幕旋转的底层原理
- Fragment 的重建由宿主 Activity 触发,AMS 销毁 Activity 时,
FragmentManager保存所有 Fragment 的状态(FragmentState)。 - 恢复时,
FragmentManager根据保存的FragmentState重新实例化 Fragment,调用onCreateView等方法。 - 源码:
// FragmentManagerImpl.java public void saveAllState() { ArrayList<FragmentState> states = new ArrayList<>(); for (Fragment f : mActive.values()) { FragmentState fs = new FragmentState(f); states.add(fs); } return states; }
进程恢复的底层原理
- AMS 保存 Activity 的
Bundle,其中包含FragmentManager的状态(FragmentState)。 - 恢复时,
FragmentManager从Bundle恢复 Fragment 实例,重建视图和状态。
2. 常见问题与底层解决方案
屏幕旋转
- 问题本质: Fragment 随 Activity 重建,视图和状态需重新绑定。
- 底层解决方案:
- ViewModel:
- ViewModel 存储在 Activity 或 Fragment 的
ViewModelStore,跨配置变化保留。
- ViewModel 存储在 Activity 或 Fragment 的
- SavedStateHandle:
- 保存状态到
Bundle,由FragmentManager和 AMS 管理。
- 保存状态到
- View Binding 清理:
- 在
onDestroyView清理视图引用,防止内存泄漏。 - 源码:
// Fragment.java void performDestroyView() { if (mView != null) { mView = null; // 清理视图 } onDestroyView(); }
- 在
- ViewModel:
进程恢复
- 问题本质: Fragment 的状态依赖
Bundle,但可能丢失复杂数据。 - 底层解决方案:
- 使用 Room 或文件存储持久化数据。
- 结合
SavedStateHandle确保关键状态恢复。
3. 代码示例(深入优化)
优化 Fragment 的状态管理:
class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val database = Room.databaseBuilder(requireContext(), AppDatabase::class.java, "app_db").build()
viewModel = ViewModelProvider(
this,
SavedStateViewModelFactory(this, MainViewModel::class.java, database.userDataDao())
).get(MainViewModel::class.java)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.userInput.observe(viewLifecycleOwner) { input ->
binding.editText.setText(input)
}
binding.editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
viewModel.saveInput(s.toString())
}
// 其他方法省略
})
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // 清理绑定
}
}
三、Service 生命周期的底层原理
1. Service 生命周期的实现机制
Service 用于执行后台任务,其生命周期由 AMS 和 ServiceRecord 管理。
核心组件与流程
- AMS:
- 管理 Service 的创建、启动、绑定和销毁。
- 通过
ServiceRecord跟踪 Service 状态。
- ActivityThread:
- 接收 AMS 的
START_SERVICE或BIND_SERVICE消息,调用 Service 的生命周期方法。
- 接收 AMS 的
- ContextImpl:
- 提供 Service 的上下文环境,处理 Intent 和 Binder。
生命周期调度流程
以 onStartCommand 为例:
- 启动 Service:
- 开发者调用
startService,通过 Binder 通知 AMS。
- 开发者调用
- AMS 处理:
- AMS 创建
ServiceRecord,检查是否需要新进程。 - 如果 Service 未运行,AMS 发送
START_SERVICE消息到ActivityThread。
- AMS 创建
- Service 执行:
ActivityThread调用handleCreateService->Service.onCreate。- 随后调用
handleServiceArgs->Service.onStartCommand。
源码(简化,基于 AOSP Android 12):
// ActivityThread.java
private void handleCreateService(CreateServiceData data) {
Service service = mInstrumentation.newService(data.info.name); // 实例化 Service
service.attach(...); // 初始化 Context
mInstrumentation.callCreateService(service); // 调用 onCreate
mServices.put(data.token, service);
}
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
s.onStartCommand(data.args, data.flags, data.startId); // 调用 onStartCommand
}
}
屏幕旋转的底层原理
- Service 不直接受屏幕旋转影响,因为它没有 UI。
- 如果 Service 与 Activity 交互,Activity 重建可能导致通信中断。
进程恢复的底层 principle
- Started Service:
- AMS 保存
ServiceRecord,记录onStartCommand的 Intent。 - 进程恢复时,AMS 根据
START_STICKY或START_REDELIVER_INTENT重启 Service。
- AMS 保存
- Bound Service:
- 绑定状态依赖客户端(通常是 Activity),进程恢复后需重新绑定。
2. 常见问题与底层解决方案
Service 被杀死后恢复
- 问题本质: 系统杀死进程后,AMS 根据
ServiceRecord和返回值(如START_STICKY)决定是否重启。 - 底层解决方案:
- Foreground Service:
- 调用
startForeground将 Service 优先级提升为前台,降低被杀死概率。 - 源码:
// Service.java public void startForeground(int id, Notification notification) { mActivityManagerService.notifyForegroundService(...); }
- 调用
- WorkManager:
- 对于非持续任务,使用 WorkManager 替代 Service,依赖系统调度。
- WorkManager 使用 JobScheduler 确保任务可靠执行。
- Foreground Service:
内存泄漏
- 问题本质: Bound Service 未解绑,导致 Activity 引用未释放。
- 底层解决方案:
- 在
onUnbind或 Activity 的onStop清理绑定。 - 使用弱引用管理 Service 引用。
- 在
3. 代码示例(深入优化)
优化 Service 的可靠性:
class MyService : Service() {
private val executor = Executors.newSingleThreadExecutor()
override fun onCreate() {
super.onCreate()
val notification = NotificationCompat.Builder(this, "channel_id")
.setContentTitle("Service Running")
.setSmallIcon(R.drawable.ic_notification)
.build()
startForeground(1, notification)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
intent?.getStringExtra("data")?.let { data ->
executor.execute {
// 执行后台任务
Log.d("MyService", "Processing: $data")
}
}
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
executor.shutdown()
}
override fun onBind(intent: Intent?): IBinder? = null
}
四、BroadcastReceiver 生命周期的底层原理
1. BroadcastReceiver 生命周期的实现机制
BroadcastReceiver 用于接收广播,其生命周期由 AMS 和 BroadcastQueue 管理。
核心组件与流程
- AMS:
- 维护广播队列(
BroadcastQueue),包括普通广播和有序广播。 - 根据 IntentFilter 匹配接收器,调度
onReceive。
- 维护广播队列(
- ActivityThread:
- 动态注册的 Receiver 通过
LoadedApk管理,AMS 将广播发送到应用进程。
- 动态注册的 Receiver 通过
- ContextImpl:
- 提供 Receiver 的上下文环境。
生命周期调度流程
- 广播发送:
- 开发者调用
sendBroadcast,AMS 接收 Intent。 - AMS 根据
IntentFilter查找匹配的 Receiver(静态或动态)。
- 开发者调用
- 广播分发:
- AMS 将广播加入
BroadcastQueue,按优先级分发。 - 对于动态 Receiver,AMS 通过 Binder 调用
ActivityThread的scheduleReceiver。
- AMS 将广播加入
- Receiver 执行:
ActivityThread调用Receiver.onReceive。
源码(简化,基于 AOSP Android 12):
// ActivityThread.java
public void scheduleReceiver(Intent intent, ActivityInfo info, int resultCode) {
BroadcastReceiver receiver = mInstrumentation.newBroadcastReceiver(info.name); // 实例化 Receiver
receiver.onReceive(mAppContext, intent); // 调用 onReceive
}
屏幕旋转的底层原理
- BroadcastReceiver 不直接受屏幕旋转影响。
- 如果 Receiver 与 Activity 交互,需注意 Activity 重建导致的通信问题。
进程恢复的底层原理
- 静态 Receiver:
- 由 AMS 直接管理,进程恢复时自动重新注册。
- 动态 Receiver:
- 依赖 Activity 或 Service,进程恢复后需重新注册。
2. 常见问题与底层解决方案
内存泄漏
- 问题本质: 动态 Receiver 未注销,导致 Activity 引用未释放。
- 底层解决方案:
- 在
unregisterReceiver清理注册。 - 源码:
// ContextImpl.java public void unregisterReceiver(BroadcastReceiver receiver) { mPackageInfo.forgetReceiverDispatcher(receiver); // 移除 Receiver }
- 在
耗时操作
- 问题本质:
onReceive执行时间受限(<10秒),否则可能触发 ANR。 - 底层解决方案:
- 使用 WorkManager 或 Service 处理耗时任务。
- WorkManager 通过 JobScheduler 调度任务,确保可靠性。
3. 代码示例(深入优化)
优化 BroadcastReceiver 的任务处理:
class MyBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
if (intent?.action == Intent.ACTION_BOOT_COMPLETED) {
val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
.setInputData(workDataOf("key" to "boot"))
.build()
WorkManager.getInstance(context).enqueue(workRequest)
}
}
}
class MyWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
val key = inputData.getString("key")
Log.d("MyWorker", "Processing: $key")
// 执行耗时任务
return Result.success()
}
}
五、综合最佳实践与底层优化
-
状态管理:
- 使用 ViewModel 和 SavedStateHandle 管理 Activity/Fragment 状态,结合 Room 持久化数据。
- 最小化
Bundle内容,复杂数据存储到数据库。
-
配置变化:
- 优先使用 ViewModel 避免重建,必要时声明
android:configChanges手动处理。 - 确保资源(如布局、字符串)动态加载。
- 优先使用 ViewModel 避免重建,必要时声明
-
进程恢复:
- 结合 AMS 的状态保存机制,使用
SavedStateRegistry和持久化存储。 - 测试进程死亡场景,确保状态一致。
- 结合 AMS 的状态保存机制,使用
-
资源清理:
- 在
onDestroyView(Fragment)、onUnbind(Service)、unregisterReceiver(BroadcastReceiver)清理引用。 - 使用弱引用或 LifecycleObserver 管理资源。
- 在
-
后台任务:
- Service 使用 Foreground Service 或 WorkManager 确保可靠性。
- BroadcastReceiver 避免耗时操作,交给 WorkManager。
六、总结
通过深入剖析 Activity、Fragment、Service 和 BroadcastReceiver 的生命周期底层原理,我们从 AMS、ActivityThread、FragmentManager 等核心组件的源码角度理解了生命周期的调度机制。屏幕旋转和进程恢复的本质在于 AMS 的状态机和 Bundle 管理,解决这些问题需要结合 ViewModel、SavedStateHandle 和持久化存储。