获取上下文的各种方法之间有什么不同?

获取上下文的各种方法之间有什么不同?

在我见过的各种Android代码中:

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

然而,对于哪一种更可取,在什么情况下应该使用,我找不到合适的解释。

对于这方面的文档的指针,以及关于如果选择错误的话可能会出现什么故障的指导,将是非常感谢的。


暮色呼如
浏览 495回答 3
3回答

慕沐林林

我同意,当涉及到Android的上下文时,文档是稀疏的,但是您可以从不同的来源拼凑一些事实。在常规的Android应用程序中,通常有两种上下文,活动和应用程序。您可能需要考虑使用应用程序上下文的时间(Activity.getApplicationContext())而不是使用活动上下文this)。基本上,应用程序上下文与应用程序相关联,并且在应用程序的整个生命周期中始终是相同的,因为活动上下文与活动相关联,并且可能在屏幕方向更改期间破坏活动时多次被销毁。不要使用getBaseContext(),只需使用您拥有的上下文即可。那是从一个柱子上Android-开发者新闻组,您可能也想考虑在那里问您的问题,因为在Android上工作的少数人会监视这个新闻组并回答问题。因此,总的来说,如果可能的话,最好使用全局应用程序上下文。

森林海

下面是我发现的关于使用context:1) .在Activity本身,使用this对于膨胀的布局和菜单,注册上下文菜单,实例化小部件,启动其他活动,创建新的Intent在Activity类中可用的首选项或其他方法。Activity.充气布局:View mView = this.getLayoutInflater().inflate(R.layout.myLayout, myViewGroup);充气菜单:@Overridepublic 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类(例如Content观察者),使用上下文替换如下:mContext = this;    // Example 1mContext = context; // Example 2哪里this或context类(活动等)的上下文。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使用。

DIEA

我的决定很简单:始终使用applicationContext。但是,我遇到了一个问题,我花了几个小时找到它,几秒钟来解决它.(换一个词.)我正在使用LayoutInflater来膨胀包含旋转器的视图。这里有两种可能性: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);我注意到:如果您使用applicationContext实例化线性Layout,那么当您单击活动中的旋转器时,您将有一个未察觉的异常,来自Dalvik虚拟机(而不是从您的代码中,这就是为什么我花了大量时间查找我的错误所在…)。如果您使用base Context,那么没关系,上下文菜单将打开,您将能够在您的选择中进行选择。下面是我的结论:我想(我还没有进一步测试它)比在您的活动中处理contextMenu时所需的base Context.该测试已经用API 8进行了编码,并在HTCRe欲(Android2.3.3)上进行了测试。我希望我的评论没有让你感到厌烦,并祝你一切顺利。快乐编码;-)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Android