在不同的Android代码中,我看到:

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

然而,我找不到任何像样的解释,说明哪种方法更可取,以及在什么情况下应该使用哪种方法。

如果您选择了错误的选项,将非常感谢您提供有关该选项的文档指针,以及关于可能出现故障的指导。


当前回答

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

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

其他回答

我只使用这个和getBaseContext从一个onClick toast(非常绿色的新手到Java和android)。当我的点击器直接在活动中,并且必须在匿名的内部点击器中使用getBaseContext时,我使用这个。我猜这就是getBaseContext的诀窍,它可能返回隐藏内部类的活动的上下文。

简单地说

getApplicationContext()正如方法名称所暗示的那样,将使你的应用程序意识到你可以从应用程序的任何地方访问的应用程序范围的细节。所以你可以在服务绑定,广播注册等中使用它。应用程序上下文将一直存在,直到应用程序退出。

getActivity()或这将使你的应用程序意识到当前屏幕,这也是可见的应用程序上下文提供的应用程序级别的细节。你想知道的关于当前屏幕的任何东西比如Window ActionBar Fragementmanger都可以通过这个context得到。基本上和活动扩展上下文。在当前组件(活动)激活之前,该上下文都是激活的

我同意,当涉及到Android中的上下文时,文档很少,但你可以从各种来源拼凑一些事实。

谷歌Android开发者官方博客上的这篇文章主要是为了帮助解决内存泄漏问题,但也提供了一些关于上下文的好信息:

在常规的Android应用程序中,您 通常有两种语境, 活动和应用程序。

Reading the article a little bit further tells about the difference between the two and when you might want to consider using the application Context (Activity.getApplicationContext()) rather than using the Activity context this). Basically the Application context is associated with the Application and will always be the same throughout the life cycle of your app, where as the Activity context is associated with the activity and could possibly be destroyed many times as the activity is destroyed during screen orientation changes and such.

我找不到任何关于何时使用getBaseContext()的东西,除了Dianne Hackborn的一篇帖子,她是谷歌的工程师之一,致力于Android SDK:

不要使用getBaseContext(),只需使用 你所拥有的环境。

这是来自Android开发人员新闻组的一篇帖子,你可能也想在那里问你的问题,因为有少数Android工作人员实际上在监控那个新闻组并回答问题。

因此,总的来说,尽可能使用全局应用程序上下文似乎更可取。

首先,我同意我们应该尽可能使用appcontext。然后是"this" in activity。我从来不需要基本的上下文。

在我的测试中,大多数情况下它们是可以互换的。在大多数情况下,您想要获得上下文的原因是访问文件、首选项、数据库等。这些数据最终会以文件的形式反映在应用程序的私有数据文件夹(/data/data/)中。无论你使用哪个上下文,它们都将被映射到相同的文件夹/文件,所以没问题。

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

以下是我在使用语境方面的发现:

1) . 在一个活动本身中,使用它来膨胀布局和菜单,注册上下文菜单,实例化小部件,启动其他活动,在一个活动中创建新的Intent,实例化首选项,或在一个活动中可用的其他方法。

膨胀布局:

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

启动一个活动:

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类(例如contenttobserver),使用上下文替换如下:

mContext = this;    // Example 1
mContext = 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;
    }
}

contenttobserver上下文替换:

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)。对于toast,通常使用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();
    }
}

最后,不要像Android框架开发人员建议的那样使用getBaseContext()。

更新:添加上下文使用示例。