android Context

来源:互联网 发布:网络适应广电总局 编辑:程序博客网 时间:2024/06/10 14:33

如何获取Context

通常我们想要获取Context对象,主要有以下四种方法
1:View.getContext,返回当前View对象的Context对象,通常是当前正在展示的Activity对象。
2:Activity.getApplicationContext,获取当前Activity所在的(应用)进程的Context对象,通常我们使用Context对象时,要优先考虑这个全局的进程Context。
3:ContextWrapper.getBaseContext():用来获取一个ContextWrapper进行装饰之前的Context,可以使用这个方法,这个方法在实际开发中使用并不多,也不建议使用。
4:Activity.this 返回当前的Activity实例,如果是UI控件需要使用Activity作为Context对象,但是默认的Toast实际上使用ApplicationContext也可以。



作者:尹star
链接:http://www.jianshu.com/p/94e0f9ab3f1d
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Context引起的内存泄露

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

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);    }}

有一个静态的Drawable对象当ImageView设置这个Drawable时,ImageView保存了mDrawable的引用,而ImageView传入的this是MainActivity的mContext,因为被static修饰的mDrawable是常驻内存的,MainActivity是它的间接引用,MainActivity被销毁时,也不能被GC掉,所以造成内存泄漏。

正确使用Context

一般Context造成的内存泄漏,几乎都是当Context销毁的时候,却因为被引用导致销毁失败,而Application的Context对象可以理解为随着进程存在的,所以我们总结出使用Context的正确姿势:
1:当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的Context。
2:不要让生命周期长于Activity的对象持有到Activity的引用。
3:尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。

总结

总之Context在Android系统中的地位很重要,它几乎无所不能,但它也不是你想用就能随便用的,谨防使用不当引起的内存问题



作者:尹star
链接:http://www.jianshu.com/p/94e0f9ab3f1d
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。