context

一个Activity就是一个Context,一个Service也是一个Context。Android程序员把“场景”抽象为Context类,他们认为用户和操作系统的每一次交互都是一个场景,比如打电话、发短信,这些都是一个有界面的场景,还有一些没有界面的场景,比如后台运行的服务(Service)。一个应用程序可以认为是一个工作环境,用户在这个环境中会切换到不同的场景,这就像一个前台秘书,她可能需要接待客人,可能要打印文件,还可能要接听客户电话,而这些就称之为不同的场景,前台秘书可以称之为一个应用程序.

Context类本身是一个纯abstract类,它有两个具体的实现子类:ContextImpl和ContextWrapper。context能干什么?context可以弹出toast,启动Activity,启动service,发送广播,操作数据库,访问资源等等

获取context对象主要有四种方法:

1.view.getContext,返回当前View对象的context对象,通常是当前正在展示的Activity对象。

2.Activity.getApplicationContext,获取当前Activity所在的进程的context对象,通常我们使用context对象时,要优先考虑这个全局的进程context.

3.ContextWrapper.getBaseContext():用来获取一个contextWrapper进行装饰之前的context,可以使用这个方法,这个方法在实际开发中使用并不多,不建议使用。

4.Activty.this 返回当前的Activity的实例,如果是UI控件需要使用Activity作为context对象,但是默认的Toast实际上使用ApplicationContext也可以。

getApplication()和getApplicationContext()区别

Application本身就是一个context,获取getApplicationContext()得到的结果就是Application本身的实例,getApplication()方法的语义性非常强,一看就是知道就是获取Application

实例,但是这个方法只有在Activity和service中才能调用的到。那么也许在绝大多数情况下我们都是在Activity或者Service中使用Application的,但是如果在其他场景,比如BroadcastReceiver也想获得Application的实例,这时就可以借助getApplicationContext()方法。

错误的单例模式:

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作为静态对象生命周期要长于普通的对象,其中也包含Activity,假如Activity a 去getInstance获得instance对象,传入this,常驻内存的singleton保存
传入的对象,并一直持有,即使Activity被销毁掉,但它的引用还存在于一个Singleton中就不可能被GC掉,这样就导致了内存泄漏。
private static Drawable mDrawable;
....

ImageVIew iv = new ImageView(this);
mDrawable = getResoures().getDrawable(R.drawable.ic_launcher);
iv.setImageDrawable(mDrawable);
ImageView保存了mDrawable的引用,而ImageView传入的this是MainActivty的mContext,因为被static修饰的mDrawable是常驻内存的,MainActivity是它的间接引用,MainActivity被销毁时,也不能被GC掉,导致内存泄漏。

正确的用法:

1.当Application的context能搞定的情况下,并且生命周期长的对象,优先使用Application的context.

2.不要让生命周期长于Activity的对象持有到Activity的引用。

3.尽量不要再Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值