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

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

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

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


当前回答

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

其他回答

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

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

几天前我读了这篇文章,问自己同样的问题。读完这篇文章后,我的决定很简单:始终使用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,那么当你点击你的活动中的旋转器,你会有一个未捕获的异常,来自dalvik虚拟机(不是从你的代码,这就是为什么我花了很多时间来寻找哪里是我的错误…)

如果你使用baseContext,那么没关系,上下文菜单将打开,你将能够在你的选项中进行选择。

所以这是我的结论:我认为(我没有进一步测试)比baseContext是必需的处理上下文菜单在你的活动…

测试使用API 8进行编码,并在HTC Desire、android 2.3.3上进行测试。

希望我的评论到目前为止没有让你厌烦,祝你一切顺利。快乐编码;-)

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

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()。

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

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

简单地说

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

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