context

Context


分类

Application的Context

Application对象以单例的形式出现,代表正在运行的APP,Application继承了ContextWrapper,所以可以认为它也是一个Context,此处将其称为“Application的Context”。

获取方式:

  • 在Activity或Service中,可通过调用getApplication()函数获取。

  • 可以通过context.getApplicationContext()获取。

Activity、Service的Context

Activity和Service同样都继承于ContextWrapper,所以也可以认为它们是Context。

BroadcastReceiver的Context

BroadcastReceiver本身不是Context,其内部也不含有Context,但在onReceive(Context context, Intent intent)中有context参数。这个context随着receiver的注册方式的不同而不同:

  • 静态注册:context为ReceiverRestrictedContext,bindService和registerReceiver被禁用

  • 动态注册:context为Activity的context

  • LocalBroadcastManager的动态注册: context为Application的context

ContentProvider的Context

ContentProvider本身不是Context,但可以通过getContext()获取一个context对象(该对象代表的是当前provider运行的context)。具体来讲:

  • 如果provider和调用者在同一个process中,context就是Application的context

  • 如果provider和调用者分属不同的进程,getContext将创建一个新的context代表此provider所运行的包。

getContext()必须在onCreate调用之后才可用,在构造器中调用将返回null。

能力

ApplicationActivityServiceContent ProviderBroadcast Receiver(静态)
显示对话框NoYesNoNoNo
启动ActivityNo1YesNo1No1No1
填充布局No2YesNo2No2No2
启动ServiceYesYesYesYesYes
绑定ServiceYesYesYesYesNo
发送BroadcastYesYesYesYesYes
注册Broadcast-ReceiverYesYesYesYesNo3
加载资源值YesYesYesYesYes

注意

  • No1表示Application的Context确实可以启动一个Activity,但是它需要创建一个新的task,会造成APP中存在不标准的回退栈,不推荐。
  • No2表示这是非法的,填充虽然可以完成,但使用的系统默认的theme,而非APP的theme。
  • No3在4.2以上,如果receiver是null(用于粘性广播,已被标注为过时),是允许的。

综上:与UI相关的功能只能由Activity的Context去处理。

注意事项

当需要保存一个context的引用时,如果它超过了你的Activity或Service的生命周期(即便只是暂时的),需要保存Application的context。

比较典型的:单例。

错误的例子:


public class CustomManager{
    private static CustomManager sInstance;

    private Context mContext;
    private CustomManager(Context context){
        mContext = context;
    }

    public static CustomManager getInstance(Context context){
        if( sInstance == null ){
            sInstance = new CustomManager(context);
        }
        return sInstance;
    }
}

原因:如果传入的context是一个Activity,则由于它在单例的实现中被引用,导致该Activity对象及其所引用的对象永远不能被垃圾回收,有内存泄漏的风险。

更好的实现:


public class CustomManager{
    private static CustomManager sInstance;

    private Context mContext;
    private CustomManager(Context context){
        mContext = context;
    }

    public static CustomManager getInstance(Context context){
        if( sInstance == null ){
            sInstance = new CustomManager(context.getApplicationContext());
        }
        return sInstance;
    }
}

另一个比较典型的例子:在后台线程或一个等待的Handler中如果需要保存Context的引用,也请使用Application的context。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值