getApplicationContext(), getBaseContext(), getApplication(), getParent()区别以及context的最终解析

首先讲一讲这四个函数的区别,后面还有我对context的一些理解

区别如下所示:

原文链接http://stackoverflow.com/questions/6854265/getapplicationcontext-getbasecontext-getapplication-getparent

翻译+我的总结如下

1. getApplicationContext() :

这个函数返回的这个Application的上下文,所以是与app挂钩的,所以在整个生命周期里面都是不变的,这个好理解,但是使用的时候要注意,该context是和引用的生命周期一致的,所以和activity生命周期挂钩的任务不要使用该context,比如网络访问,防止内存泄露

2. getBasecontext():

stackoverflow上面写的是,这个函数不应该被使用,用Context代替,而Context是与activity相关连,所以当activity死亡后可能会被destroyed,我举个我自己写的例子

public Dialog displayDialog(int choice)
    {
    switch(choice){
    case 0:
    AlertDialog aDialog = new AlertDialog.Builder(this)
    .setIcon(R.drawable.ic_launcher)
    .setTitle("Hello World")
    .setPositiveButton("OK", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(getBaseContext(), "OK clicked", Toast.LENGTH_SHORT).show();
}
}).......


这个例子中的getBaseContext()就不能被this代替,因为上面的this返回的是这个activity的context,而在这个onClick函数中如果使用this的话,则返回的是这个AlertDialog的context,所以要使用的是当前activity名.this 去使用,比如当前activity为 TestActivity,那么在里面就是用TestActivity.this即可


3. getApplication():

getApplication只能被Activity和Services使用,虽然在现在的android的实现中,getApplication和getApplicationContext返回一样的对象,但也不能保证这两个函数一样(例如在特殊的提供者来说),所以如果你想得到你在Manifest文件里面注册的App class,你不要去调用getApplicationContext,以为你可能得不到你所要的app实例(你显然有测试框架的经验)。。。。

翻译完成,一目了然(哪里翻译错误,请指出,水B一只),原文:

getApplication() is available to Activity and Services only. Although in current Android Activity and Service implementations, getApplication() and getApplicationContext() return the same object, there is no guarantee that this will always be the case (for example, in a specific vendor implementation). So if you want the Application class you registered in the Manifest, you should never call getApplicationContext() and cast it to your application, because it may not be the application instance (which you obviously experienced with the test framework).

4. getParent() :

返回activity的上下文,如果这个子视图的话,换句话说,就是当在子视图里面调用的话就返回一个带有子视图的activity对象,一目了然。。。


5.getActivity():

在fragment中使用,返回该fragment所依附的activity上下文

6.this

记住Activity,Service类,Application类是继承自Context类的,所以在有的时候需要上下文,只需要使用this关键字即可,但是有的时候再线程里面,this关键字的意义就改变了,但这个时候如果需要上下文,则需要使用 类名.this,这样就可以了

这里有点注意的:

做项目时遇见的,提一下吧,动态注册广播,在调用registerBroadcast函数的时候,需要传入一个上下文和broadcastReceiver,查看源码可以知道,存储的时候context是作为一个key的作用,所以使用同一个context来注册同一个广播,onreceive只会调用一次,但是如果使用不同的context,则会调用多次,虽然不调用unregisterBroadcast有时也没事,不会报错,但是一定不要忘记取消注销


后续:为了简化context的使用方法,现在有这么一种方法,就是在Application类里面维护一个弱引用:

/** 用来保存当前该Application的context */
private static Context instance;
/** 用来保存最新打开页面的context */
private volatile static WeakReference<Context> instanceRef = null;

再写一个方法,
public static Context getInstance(){
        if (instanceRef == null || instanceRef.get() == null){
            synchronized (RootApplication.class) {
                if (instanceRef == null || instanceRef.get() == null) {
                    Context context = ActivityManager.getInstance().getActivity();
                    if (context != null)
                        instanceRef = new WeakReference<>(context);
                    else {
                        instanceRef = new WeakReference<>(instance);
                        L.w("请确保RootActivity调用setInstanceRef方法");
                    }
                }
            }
        }
        return instanceRef.get();
    }


最后在应用的Activity基类中(这个应该有的吧)加上两个语句:


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        RootApplication.setInstanceRef(this);
    }


    protected void onResume() {
        super.onResume();
        //也要在onresume函数里面进行设置,保证弱引用一直引用当前的可见页面
        RootApplication.setInstanceRef(this);
    }


这样每次调用application的getInstance()方法一定能够返回一个context,而且是当前唯一可见activity的context,其他地方就可以直接使用了,不用到处传递context,再此处统一维护即可,

我写了一个android framework,里面就用到了这个方法,一个关于android应用框架的库和测试类:https://github.com/zhaozepeng/Android_framework,包含了自己的一些对android应用的想法,还未完成,如果需要一起code,联系我,小白一个,望多多指点

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值