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

*爱你&永不变心* 提交于 2020-02-26 03:57:37

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

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

但是,我找不到任何合适的解释,哪些更好,以及在什么情况下应该使用。

关于这方面的文件的指示,以及关于如果选择了错误的可能会破坏的指导,将非常感激。


#1楼

我同意在Android中使用Contexts时文档很少,但您可以将各种来源的一些事实拼凑起来。

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

在常规Android应用程序中,通常有两种Context,Activity和Application。

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

我找不到什么关于什么时候使用getBaseContext(),而不是来自Dianne Hackborn的帖子,Dianne Hackborn是一位在Android SDK上工作的Google工程师:

不要使用getBaseContext(),只需使用你拥有的Context。

这是来自android-developers新闻组的帖子,你可能也想考虑在那里问你的问题,因为在Android上工作的少数人实际监控新闻组并回答问题。

总的来说,似乎最好在可能的情况下使用全局应用程序上下文。


#2楼

以下是我发现的关于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)。 对于Listeners和其他类型的Android类(例如ContentObserver),使用Context替换,如:

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

thiscontext是类的上下文(Activity等)。

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)。 对于Toasts,通常使用getApplicationContext() ,但在可能的情况下,使用从Activity,Service等传递的上下文。

使用应用程序的上下文:

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

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


#3楼

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

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

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


#4楼

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

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

#5楼

简单来说

getApplicationContext()作为方法名称建议将使您的应用程序了解您可以从应用程序中的任何位置访问的应用程序范围的详细信息。 因此,您可以在服务绑定,广播注册等中使用它。 Application context将一直存在,直到应用程序退出。

getActivity()this将使您的应用程序了解当前屏幕,该屏幕也可以看到应用application context提供的application context程序级别详细信息。 因此,无论您想了解当前屏幕如Window ActionBar Fragementmanger等,都可以使用此上下文。 基本上和Activity扩展Context 。 此上下文将一直存在,直到当前组件(活动)处于活动状态

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!