一句话总结:
Context 是 Android 应用的「万能工具包」,能让你访问资源、启动界面、调用系统服务,但不同类型的 Context 就像不同权限的钥匙——有的能开所有门(全局),有的只能开自己房间(界面相关)。
Context 的三大核心功能:
- 访问资源:
获取图片、字符串、颜色等资源,比如context.getString(R.string.app_name)。 - 启动组件:
启动 Activity、Service、发送广播,比如context.startActivity(intent)。 - 获取系统服务:
调用系统功能(如定位、传感器、存储),比如context.getSystemService(Context.LOCATION_SERVICE)。
Context 的两种常见类型:
1. Activity Context(界面上下文)
-
角色:像「房间管理员」,只能管理自己的房间(Activity)。
-
生命周期:和 Activity 一致,Activity 销毁,这把钥匙就失效。
-
能做什么:
- 启动新的 Activity(需要任务栈信息)。
- 弹窗(如
AlertDialog)、加载布局(如LayoutInflater)。 - 操作界面相关的功能(如主题、动画)。
-
风险:如果被全局对象(如单例)持有,会导致内存泄漏(房间关了,钥匙还在,管理员无法下班)。
2. Application Context(全局上下文)
-
角色:像「大楼物业」,管理整个应用(无论哪个界面)。
-
生命周期:从应用启动到关闭一直存在。
-
能做什么:
- 获取全局资源(如数据库、配置文件)。
- 初始化第三方库(如 Firebase、推送服务)。
- 获取系统服务(如传感器、定位)。
-
限制:
- 不能直接操作界面(如弹窗、启动 Activity)。
- 无法访问界面主题或动画。
什么时候用哪种 Context?
| 场景 | 推荐 Context | 原因 |
|---|---|---|
| 弹窗、启动新 Activity | Activity Context | 需要界面相关的上下文信息(如任务栈、主题)。 |
| 初始化全局库(如数据库) | Application Context | 生命周期长,避免内存泄漏。 |
| 获取系统服务(如定位) | Application Context | 除非服务需要界面绑定(如对话框),否则优先用全局上下文。 |
| 加载布局(XML) | Activity Context | 需要访问界面主题或样式。 |
| 发送广播 | 两者均可 | 根据广播类型决定(界面相关用 Activity,全局用 Application)。 |
错误示例:用错 Context 的后果
-
用 Application Context 弹窗 → 崩溃:
AlertDialog.Builder(applicationContext).show() // ❌ 崩溃!无法添加窗口到不存在的界面 -
单例持有 Activity Context → 内存泄漏:
object MySingleton { var context: Context? = null // 如果传了 Activity Context,Activity 销毁后无法回收! }
超简记忆法:
- Activity Context → “只管自己屋” (界面操作,命短易泄漏)。
- Application Context → “全楼通” (全局事务,命长安全)。
总结:
-
Context是 Android 开发的基石,几乎所有操作都需要它。 -
黄金法则:
- 涉及界面 → 用
Activity Context。 - 全局或后台 → 用
Application Context。
- 涉及界面 → 用
-
避坑指南:
- 永远不要让单例或静态变量持有
Activity Context! - 不确定时优先用
Application Context(除非必须操作界面)。
- 永远不要让单例或静态变量持有
记住:钥匙要对,门才能开!