2009-06-22 273 views
352

在Android的代码的各种比特我看到:应该使用获取上下文的各种方法之间有什么区别?

public class MyActivity extends Activity { 
    public void method() { 
     mContext = this; // since Activity extends Context 
     mContext = getApplicationContext(); 
     mContext = getBaseContext(); 
    } 
} 

但是我无法找到任何像样的解释这是优选的,在什么情况下。

指向这方面的文档,以及有关如果选择了错误选项可能会破坏的指导,将不胜感激。

+2

此链接可能会对您有所帮助。通过[this](http://droidpassion.blogspot.in/2012/03/all-about-context.html).. – Aju 2012-05-28 15:30:44

回答

284

我同意文档在Android中的上下文时很少见,但您可以从各种来源拼凑出一些事实。

在谷歌官方Android开发者博客This blog post写主要是为了帮助解决内存泄漏,但提供了有关上下文一些有用的信息,以及:

在常规的Android应用程序,你 通常有两种上下文, 活动和应用程序。

阅读文章一点点进一步讲述两个之间的区别时,你可能要考虑使用应用程序上下文(Activity.getApplicationContext()),而不是使用活动情境this)。基本上,应用程序上下文与应用程序相关联,并且在应用程序的整个生命周期中始终保持相同,因为活动上下文与活动相关联,并且可能会多次销毁,因为活动在屏幕方向更改期间被销毁;这样。

我找不到任何关于何时使用getBaseContext()以外,从戴安娜Hackborn,在谷歌工程师的工作在Android SDK的一个帖子真的什么:

不要使用getBaseContext() ,只需使用 即可。

这是从上android-developers newsgroup后,你可能要考虑问你的问题有作为,因为Android的实际显示器上工作的人屈指可数该新闻组并回答问题。

因此,总体而言,尽可能使用全局应用程序上下文似乎更可取。

+11

当我有一个活动A可以启动活动B,反过来,它可以重新启动A与CLEAR_TOP标志(可能重复多次这个循环) - 在这种情况下,我应该使用什么上下文以避免建立大量的引用上下文?戴安娜说使用'this'而不是getBaseContext,但是接下来......大部分时间A都会被重用,但是有些情况下会创建A的新对象,然后老A会泄漏。所以看起来getBaseContext是大多数情况下最合适的选择。然后不清楚为什么`不要使用getBaseContext()`。有人能澄清这一点吗? – JBM 2011-03-30 12:21:29

+0

如何访问不扩展Activity的类内的上下文对象? – Cole 2011-04-19 20:23:01

+1

@Cole,你可以创建一个类,我们将在这里调用“ExampleClass”,它的构造函数需要一个Context对象并实例化一个类实例变量“appContext”。然后,您的Activity类(或任何其他类)可以调用ExampleClass方法,该方法使用ExampleClass的“appContext”实例变量。 – Archie1986 2011-06-24 17:02:49

6

首先,我同意我们应尽可能使用appcontext。然后“这个”在活动中。我从来没有需要basecontext。

在我的测试中,大多数情况下它们可以互换。在大多数情况下,您希望获取上下文的原因是访问文件,首选项,数据库等。这些数据最终会反映为应用程序专用数据文件夹(/ data/data /)中的文件。无论您使用哪种上下文,它们都将映射到相同的文件夹/文件,因此您无需担心。

这就是我所观察到的。也许有些情况下你应该区分它们。

3

在某些情况下,您可以在线程中运行某些内容时使用Activity上下文而非应用程序上下文。当线程完成执行并且您需要将结果返回给调用者活动时,您需要使用处理程序的上下文。

((YourActivity) context).yourCallbackMethod(yourResultFromThread, ...); 
0

onClick(非常环保小白与Java和Android设备)敬酒时,我只用这和getBaseContext。当我的阅读器直接处于活动状态并且必须在匿名内部点击器中使用getBaseContext时,我会使用它。我猜这跟getBaseContext差不多,它可能会返回内部类隐藏活动的上下文。

+0

这是错误的,它返回活动本身的基本上下文。为了从匿名内部类获得活动(你想用作上下文的活动)使用类似`MyActivity.this`的东西。您所描述的使用基本上下文可能不会导致问题,但它是错误的。 – nickmartens1980 2013-12-17 13:42:35

12

我几天前看了这个帖子,问自己同样的问题。我读完这个后做出的决定很简单:总是使用applicationContext。

不过,我遇到了这样一个问题,我花了几个小时找到它,并在几秒钟解决这个问题......(改变一个字......)

我使用的是LayoutInflater到给包含Spinner的视图充气。

因此,这里有两种可能性:

1)

LayoutInflater layoutInflater = LayoutInflater.from(this.getApplicationContext()); 

2)

LayoutInflater layoutInflater = LayoutInflater.from(this.getBaseContext()); 

然后,我做这样的事情:

// managing views part 
    View view = ContactViewer.mLayoutInflater.inflate(R.layout.aViewContainingASpinner, theParentView, false); 
    Spinner spinner = (Spinner) view.findViewById(R.id.theSpinnerId); 
    String[] myStringArray = new String[] {"sweet","love"}; 

    // managing adapter part 
    // The context used here don't have any importance -- both work. 
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this.getApplicationContext(), myStringArray, android.R.layout.simple_spinner_item); 
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
    spinner.setAdapter(adapter); 

    theParentView.addView(view); 

我注意到:如果你实例化你的linearLayout与applicationContext,然后当你点击你的活动中的微调,你将会有一个未捕获的异常,来自dalvik虚拟机(不是来自你的代码,这就是为什么我花了很多时间来找到我的位置错误...)。

如果您使用baseContext,那么没关系,上下文菜单将打开,您将可以在您的选择中进行选择。

因此,这里是我的结论:我想(我还没有进一步测试它)不是与文本菜单中的活动打交道时的baseContext需要...

测试已经完成与API 8编码,并在HTC Desire,android 2.3.3上测试。

我希望我的评论至今没有让你感到厌倦,并祝你一切顺利。快乐编码;-)

41

这就是我关于使用context发现:

1)。在一个Activity本身,使用this用于充气布局和菜单,注册上下文菜单,实例化部件,启动其他活动,一个Activity中创建新Intent,在Activity可用实例的偏好,或其他方法。

膨胀布局:

View mView = this.getLayoutInflater().inflate(R.layout.myLayout, myViewGroup); 

充气菜单:

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    super.onCreateOptionsMenu(menu); 
    this.getMenuInflater().inflate(R.menu.mymenu, menu); 
    return true; 
} 

注册上下文菜单:

this.registerForContextMenu(myView); 

实例化插件:

TextView myTextView = (TextView) this.findViewById(R.id.myTextView); 

启动一个Activity

Intent mIntent = new Intent(this, MyActivity.class); 
this.startActivity(mIntent); 

实例化的偏好:

SharedPreferences mSharedPreferences = this.getPreferenceManager().getSharedPreferences(); 

2)。对于应用程序范围的类,使用getApplicationContext()作为该上下文存在的应用程序的生命周期。

检索当前Android包的名称:

public class MyApplication extends Application {  
    public static String getPackageName() { 
     String packageName = null; 
     try { 
      PackageInfo mPackageInfo = getApplicationContext().getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), 0); 
      packageName = mPackageInfo.packageName; 
     } catch (NameNotFoundException e) { 
      // Log error here. 
     } 
     return packageName; 
    } 
} 

绑定的应用程序范围内类:

Intent mIntent = new Intent(this, MyPersistent.class); 
MyServiceConnection mServiceConnection = new MyServiceConnection(); 
if (mServiceConnection != null) { 
    getApplicationContext().bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE); 
} 

3)。侦听器以及其它类型的Android类(例如ContentObserver)的,使用上下文取代,如:

mContext = this; // Example 1 
mContext = context; // Example 2 

其中thiscontext是一个类(活动等)的情况下。

Activity上下文取代:

public class MyActivity extends Activity { 
    private Context mContext; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState);   
     mContext = this; 
    } 
} 

侦听上下文取代:

public class MyLocationListener implements LocationListener { 
    private Context mContext; 
    public MyLocationListener(Context context) { 
     mContext = context; 
    } 
} 

ContentObserver上下文取代:

public class MyContentObserver extends ContentObserver { 
    private Context mContext; 
    public MyContentObserver(Handler handler, Context context) { 
     super(handler); 
     mContext = context; 
    } 
} 

4)。对于BroadcastReceiver(包括内嵌/嵌入式接收器),请使用接收器自己的上下文。

外部BroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     final String action = intent.getAction(); 
     if (action.equals(Intent.ACTION_SCREEN_OFF)) { 
      sendReceiverAction(context, true); 
     } 
     private static void sendReceiverAction(Context context, boolean state) { 
      Intent mIntent = new Intent(context.getClass().getName() + "." + context.getString(R.string.receiver_action)); 
      mIntent.putExtra("extra", state); 
      context.sendBroadcast(mIntent, null); 
     } 
    } 
} 

内联/嵌入式BroadcastReceiver

public class MyActivity extends Activity { 
    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      final boolean connected = intent.getBooleanExtra(context.getString(R.string.connected), false); 
      if (connected) { 
       // Do something. 
      } 
     } 
    }; 
} 

5)。对于服务,使用服务自己的上下文。

public class MyService extends Service { 
    private BroadcastReceiver mBroadcastReceiver; 
    @Override 
    public void onCreate() { 
     super.onCreate(); 
     registerReceiver(); 
    } 
    private void registerReceiver() { 
     IntentFilter mIntentFilter = new IntentFilter(); 
     mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF); 
     this.mBroadcastReceiver = new MyBroadcastReceiver(); 
     this.registerReceiver(this.mBroadcastReceiver, mIntentFilter); 
    } 
} 

6)。对于干杯,一般采用getApplicationContext(),但在可能的情况,使用从一个活动,服务传递的上下文等

应用程序的用途的上下文:从源传递

Toast mToast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG); 
mToast.show(); 

使用上下文:

public static void showLongToast(Context context, String message) { 
    if (context != null && message != null) { 
     Toast mToast = Toast.makeText(context, message, Toast.LENGTH_LONG); 
     mToast.show(); 
    } 
} 

而在去年,不使用getBaseContext()通过Android的框架开发商建议。

更新:添加Context用法的示例。

1

在简单的话

getApplicationContext()作为方法名建议将您的应用程序知道的,你可以在该应用的任何地方访问应用广泛的细节。所以你可以利用这个服务绑定,广播注册等Application context将活着,直到应用程序退出。

getActivity()this将使您的应用程序知道当前屏幕,也可以看到application context提供的应用程序级别详细信息。所以无论你想了解当前的屏幕如WindowActionBarFragementmanger等都可以在这种情况下使用。基本上和Activity延伸Context。此上下文将一直存在,直到当前组件(活动)存活为止

相关问题