之前学习Toast的时候关于Toast.makeText()方法的第一个参数做了简单说明,现在详细说明一下这个Context。
Context是一个抽象基类,通过它访问当前包的资源(getResources、getAssets)和启动其他组件(Activity、Service、Broadcast)以及得到各种服务(getSystemService)等。
Context提供了一个应用的运行环境,在Context的大环境里,应用才可以访问资源,才能完成和其他组件、服务的交互,Context定义了一套基本的功能接口,可以理解为一套规范,而Activity和Service,
Application
是实现了这套规范的子类(
实际是被ContextImpl类统一实现的
)
程序中共有的Context数目公式为:
总Context实例个数 = Service个数 + Activity个数 + 1(Application对应的Context实例)
使用Context时的引用问题
1,内部类问题
方法
参数是Context时,一般在Activity中我们直接用this代替,代表调用者的实例为Activity,而到了一个button的onClick(View view)等方法时,我们用this时就会报错,所以我们可能使用ActivityName.this来解决,主要原因
Activity中的匿名类或者内部类中使用的话,不能直接用this,因为此时this指的是这个内部类,所以要访问外部类的Activity就要用
ActivityName
.this
2,生命周期问题
Activty、Service的Context都是每次创建的,而不是全局唯一,所以不要将Activity 、Service当做全局Context引用,这样会导致Activity无法销毁,一直被引用者。
而应该用通过context.getApplicationContext()得到的ApplicationContext(它的生命周期和整个应用程序一致
)
Context的应用场景
图中数字解释:
数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。
数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。
数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视)
注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。
总的来说跟UI相关的,都应该使用Activity做为Context来处理;其他的一些操作,Service,Activity,Application等实例都可以,注意Context引用的持有,防止内存泄漏。