android使用枚举类型 context,Android基础知识(一)------Context

Context

1.context是一个抽象类,定义了一些枚举和获取资源方法

继承关系如下:

Context --> ContextImpl

| |

v |

ContextWrapper

|

-----------------------------------------------

| | |

v v v

Application Service ContextThemeWrapper

|

v

Activity

ContextThemeWrapper与ContextWrapper的区别:

在于为Activity加载定义的Theme中的样式,Application和Service都不需要界面上的展示

2.如何保证访问资源的唯一性?

我们直接来看ContextImpl中的源码

private ContextImpl(ContextImpl container, ActivityThread mainThread,

LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags,

Display display, Configuration overrideConfiguration, int createDisplayWithId) {

mOuterContext = this;

......

mPackageInfo = packageInfo;

mResourcesManager = ResourcesManager.getInstance();

.....

Resources resources = packageInfo.getResources(mainThread);

if (resources != null) {

if (displayId != Display.DEFAULT_DISPLAY

|| overrideConfiguration != null

|| (compatInfo != null && compatInfo.applicationScale

!= resources.getCompatibilityInfo().applicationScale)) {

if (container != null) {

// This is a nested Context, so it can't be a base Activity context.

// Just create a regular Resources object associated with the Activity.

resources = mResourcesManager.getResources(

activityToken,

packageInfo.getResDir(),

packageInfo.getSplitResDirs(),

packageInfo.getOverlayDirs(),

packageInfo.getApplicationInfo().sharedLibraryFiles,

displayId,

overrideConfiguration,

compatInfo,

packageInfo.getClassLoader());

} else {

// This is not a nested Context, so it must be the root Activity context.

// All other nested Contexts will inherit the configuration set here.

resources = mResourcesManager.createBaseActivityResources(

activityToken,

packageInfo.getResDir(),

packageInfo.getSplitResDirs(),

packageInfo.getOverlayDirs(),

packageInfo.getApplicationInfo().sharedLibraryFiles,

displayId,

overrideConfiguration,

compatInfo,

packageInfo.getClassLoader());

}

}

}

mResources = resources;

.....

}

首先一个应用只有唯一的mPackageInfo这个能够保证,mResourcesManager是取的一个单例。

3.单例模式的正确运用

在一个需要使用context来初始化的单例中,我们需要在获取单例是传入context。

我们已有的只是告诉我们,持有activity的context在activity销毁之后会造成内存泄漏,且单例一般如工具类都需要做到与应用的生命周期相同,所以我们可以直接使用Application的context来进行初始化。

public class Singleton {

private static volatile Singleton instance = null;

private Context mContext;

public Singleton(Context context) {

this.mContext = context;

}

public Singleton getInstance(Context context) {

if (instance == null) {

synchronized (Singleton.class) {

if (instance == null) {

instance = new Singleton(context.getApplicationContext());

}

}

}

return instance;

}

}

从代码中可以看到,用context的getApplicationContext()来保证我们使用的只会是Application的Context。

4.如果用Application的context是否可以启动一个activity,会出现什么异常情况?

我们直接尝试利用Application的Context来启动Activity,跟网上说的会报异常或者创建在新的任务中的结论不符啊,有大神看到麻烦指点下。

--!

5.如果用Application的context是否可以inflateLayout,会出现什么异常情况?

由于Activity是继承于ContextThemeWrapper,所以用Activity的Context创建的View或者Dialog等会带有自定义的Theme,若使用Service或者Application的Context则会使用系统默认的样式。

6.避免将context用来创建static变量

网上的一个例子:

private static Drawable sDrawable;

sDrawable = context.getDrawable(R.mipmap.ic_launcher);

将一个静态变量drawable用context(假设为Activity的context)进行初始化,由于被静态变量所持有,会导致内存泄漏问题。

tips

不要让比context生命周期长的对象持有该context,如在Activity中使用presenter的问题,必须要进行相应的解决。

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值