Android各种获取Context方法

Android各种获取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类里面维护一个弱引用:

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

再写一个方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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基类中(这个应该有的吧)加上两个语句:

1
2
3
4
public  void  onCreate(Bundle savedInstanceState) { 
     super .onCreate(savedInstanceState); 
     RootApplication.setInstanceRef( this ); 
1
2
3
4
5
protected  void  onResume() { 
     super .onResume(); 
     //也要在onresume函数里面进行设置,保证弱引用一直引用当前的可见页面 
     RootApplication.setInstanceRef( this ); 

  

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

你可能感兴趣的:(Android)