为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

暮色呼如 2019-06-23 15:49:24
获取上下文的各种方法之间有什么不同?在我见过的各种Android代码中: public class MyActivity extends Activity {     public void method() {        mContext = this;    // since Activity extends Context        mContext = getApplicationContext();        mContext = getBaseContext();     }  }然而,对于哪一种更可取,在什么情况下应该使用,我找不到合适的解释。对于这方面的文档的指针,以及关于如果选择错误的话可能会出现什么故障的指导,将是非常感谢的。
查看完整描述

3 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

我同意,当涉及到Android的上下文时,文档是稀疏的,但是您可以从不同的来源拼凑一些事实。

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

您可能需要考虑使用应用程序上下文的时间(Activity.getApplicationContext())而不是使用活动上下文this)。基本上,应用程序上下文与应用程序相关联,并且在应用程序的整个生命周期中始终是相同的,因为活动上下文与活动相关联,并且可能在屏幕方向更改期间破坏活动时多次被销毁。

不要使用getBaseContext(),只需使用您拥有的上下文即可。

那是从一个柱子上Android-开发者新闻组,您可能也想考虑在那里问您的问题,因为在Android上工作的少数人会监视这个新闻组并回答问题。

因此,总的来说,如果可能的话,最好使用全局应用程序上下文。


查看完整回答
反对 回复 2019-06-23
?
森林海

TA贡献2011条经验 获得超2个赞

下面是我发现的关于使用context:

1) .Activity本身,使用this对于膨胀的布局和菜单,注册上下文菜单,实例化小部件,启动其他活动,创建新的IntentActivity类中可用的首选项或其他方法。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

哪里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使用。


查看完整回答
反对 回复 2019-06-23
?
DIEA

TA贡献1820条经验 获得超2个赞

我的决定很简单:始终使用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)上进行了测试。

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


查看完整回答
反对 回复 2019-06-23
  • 3 回答
  • 0 关注
  • 494 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信