Android Context 是什么?
理解Context
- 我们可以理解为“上下文”:它贯穿整个应用;
- 也可以理解成“运行环境”:它提供了一个应用运行所需要的信息,资源,系统服务等;
- 同样可以理解成“场景”:用户操作和系统交互这一过程就是一个场 景,比如Activity之间的切换,服务的启动等都少不了Context。
Context继承关系
Context源码分析
ContextImpl—真正实现Context功能的类
class ContextImpl extends Context {
//整个App的主线程
final ActivityThread mMainThread;
//整个App的相关信息
final LoadedApk mPackageInfo;
//资源解析器
private final ResourcesManager mResourcesManager;
//App资源类
private final Resources mResources;
//外部Context的引用
private Context mOuterContext;
//默认主题.
private int mThemeResource = 0;
private Resources.Theme mTheme = null;
//包管理器
private PackageManager mPackageManager;
................................
//以下是静态区注册系统的各种服务,多大五六十种系统服务,因此每个持有Context引用的对象都可以随时通过getSystemService方法来轻松获取系统
服务。
static {
registerService(ACCESSIBILITY_SERVICE, new
ServiceFetcher() {
public Object getService(ContextImpl ctx)
{
return
AccessibilityManager.getInstance(ctx);
}});
registerService(CAPTIONING_SERVICE, new
ServiceFetcher() {
public Object getService(ContextImpl ctx)
{
return new CaptioningManager(ctx);
}});
registerService(ACCOUNT_SERVICE, new
ServiceFetcher() {
public Object createService(ContextImpl
ctx) {
IBinder b =
ServiceManager.getService(ACCOUNT_SERVICE);
IAccountManager service =
IAccountManager.Stub.asInterface(b);
return new AccountManager(ctx,
service);
}});
........................
}
.................
//启动Activity的地方
@Override
public void startActivity(Intent intent, Bundle
options) {
warnIfCallingFromSystemProcess();
if
((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside
of an Activity "
+ " context requires the
FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(),
mMainThread.getApplicationThread(), null,
(Activity)null, intent, -1, options);
}
..........
//启动服务的地方
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
...............
}
LayoutInflater inflater = LayoutInflater.from(mContext)*;*
View layout =
inflater.inflate(R.layout.activity_main,null)*;*
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not
found.");
}
return LayoutInflater;
}
Context内存泄漏问题
- 静态资源导致的内存泄漏
- 单例模式导致内存泄漏
总结 Context是什么?
- Context是”运行上下文环境“,从代码角度看 Application,Service,Activity都是Context。
- 所有Context都是在应用的主线程ActivityThread中创建的,由于 Application,Service,Activity的祖先都是Context抽象类,所以在创 建它们的同时也会为每一个类创建一个ContextImpl类,ContextImpl 是Context的子类,真正实现Context功能方法的类。因此 Application,Service,Activity都关联着一个ContextImpl对象。
- 尽量少用Context对象去获取静态变量,静态方法,以及单例对象。 以免导致内存泄漏。
- 在创建与UI相关的地方,比如创建一个Dialog,或者在代码中创建一 个TextView,都用Activity的Context去创建。然而在引用静态资源, 创建静态方法,单例模式等情况下,使用生命周期更长的Application 的Context才不会导致内存泄漏