Android应用模型是基于组件的应用设计模式,组件的运行要有一个完整的Android工程环境,在这个环境下,Activity、Service等系统组件才能够正常工作
Context的源码注释说明
Context提供了关于应用环境全局信息的接口,它是一个抽象类,它的执行为Android系统所提供
它允许获取以应用为特征的资源和类型,是一个统领一些资源(应用程序环境变量等)的上下文
Activity,Service,Application正是因为继承实现自Context
所以能执行一些获取资源的函数,例如getApplicationContext和getResources().getDrawable()根据id获取drawable资源
具体:弹出Toast、启动Activity、启动Service、发送广播、操作数据库,操作文件等等都需要用到Context。
Context相关成员
Context
Context类本身是一个纯abstract类,提供一些功能和静态常量的规范
ContextImpl
真正功能的实现类,接收到通过Binder机制 获取底层服务得来的参数赋于自身 并实现抽象方法
应用程序中所调用的各种Context类的方法,其实现均来自于该类
ContextWrapper
ContextWrapper类,如其名所言,这只是一个包装而已,
ContextWrapper构造函数中必须包含一个真正的Context引用,同时ContextWrapper中提供了attachBaseContext()用于给ContextWrapper对象中指定真正的Context对象
真正的context即实现过的ContextImpl,这样就能保证装饰类的子类也能拥有context提供的功能,在这基础上 装饰了其他功能
Service
Service是不需要主题的,因为Service是没有界面的后台场景,所以直接继承于ContextWrapper
startService和bindService实际的实现都是在ContextImpl中通过AMS调用底层service服务
service类在其基础上增加了一些管理和控制功能
Application
Application是用于保存全局应用状态的基础类,而且是单例模式,生命周期贯穿整个应用的运行
基于这一点,我们可以利用它的全局单例,保存一些系统运行时的状态信息,和初始化的动作
其中的方法大多是回调 利于我们在不同应用状态下开发
ContextThemeWrapper
如其名所言,其内部包含了与主题(Theme)相关的接口
这里所说的主题就是指在AndroidManifest.xml中通过android:theme为Application元素或者Activity元素指定的主题
在构造方法中传入主题资源,并根据资源做各自主题相关操作
Activity
Activity需要主题 继承自ContextThemeWrapper 可以操作Context资源 可以设置主题资源 并实现了各自接口 才使得四大组件之一的Activity显得十分重要
一个应用程序有几个Context
Context数量=activity个数+service个数+1
Context引起的内存泄露
单例
public class Singleton {
private static Singleton instance;
private Context mContext;
private Singleton(Context context) {
this.mContext = context;
}
public static Singleton getInstance(Context context) {
if (instance == null) {
instance = new Singleton(context);
}
return instance;
}
}
instance作为静态对象常驻与内存,其生命周期要长于普通的对象
如果getInstance传入的是Activity 那么instance会持有activity引用 导致activity无法被销毁回收
View持有Activity引用
public class MainActivity extends Activity {
private static Drawable mDrawable;
@Override
protected void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_main);
ImageView iv = new ImageView(this);
mDrawable = getResources().getDrawable(R.drawable.ic_launcher);
iv.setImageDrawable(mDrawable);
}
}
在iv.setImageDrawable(mDrawable);设置drawable中进行了这个操作
mDrawable.setCallback(this); 静态的Drawable对象设置了对imageview的引用?老版本为强引用:新版本为弱引用 导致drawable->imageview->activity的引用链 导致无法回收
总结
Reference From: