Intereting Posts
Правильный способ воспроизведения коротких звуков Android? Можно ли использовать один файл ключей для подписи двух разных приложений? Не может сгенерировать подписанный APK из студии Android «Выполнение не выполнено для задачи»: packageRelease '" Запуск Ionic при вызове throw «Невозможно прочитать свойство« Клавиатура »неопределенного» @ app.js: 14 Автоматическая загрузка автономного языка распознавания речи на Android Отредактируйте AndroidManifest при компиляции для удаления API-ключа Слушайте входящие звонки через BroadcastReceiver, без PhoneStateIntentReceiver или PhoneStateListener Checkbox не установлен, когда я просматриваю список на Android Android-Studio: проекты Gradle не будут строить без подключения к интернету даже в «автономном режиме», Что нового в OnPreferenceChangeListener и OnSharedPreferenceChangeListener Как показать и скрыть ActionBar с помощью AppCompat v.7 HandlerThread vs Executor – Когда еще один подход к другому? Подтверждение SSL-протокола OkHttp отменено в Android Достоверность количества процессоров Как лучше сохранить статус покупки InApp локально?

В чем разница между различными методами получения контекста?

В различных бит кода Android я видел:

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

Однако я не могу найти подходящего объяснения, которое предпочтительнее, и при каких обстоятельствах, которые следует использовать.

Указатели на документацию по этому поводу и руководство о том, что может сломаться, если выбрано неправильное, будут высоко оценены.

Solutions Collecting From Web of "В чем разница между различными методами получения контекста?"

Я согласен с тем, что документация разрешена, когда речь заходит о Contexts на Android, но вы можете собрать несколько фактов из разных источников.

Это сообщение в блоге на официальном блоге разработчиков Google Android было написано в основном, чтобы помочь устранить утечки памяти, но также содержит некоторую полезную информацию о контекстах:

В обычном приложении для Android обычно есть два типа контекста, активности и приложения.

Чтение статьи немного подробнее рассказывает о различии между this двумя и когда вы можете захотеть использовать приложение Context ( Activity.getApplicationContext() ), а не использовать контекст Activity this ). В основном контекст приложения связан с Приложением и всегда будет одинаковым на протяжении всего жизненного цикла вашего приложения, где, поскольку контекст Activity связан с активностью и может быть уничтожен многократно, поскольку действие уничтожается во время изменений ориентации экрана и например.

Я не мог найти ничего о том, когда использовать getBaseContext (), кроме сообщения от Dianne Hackborn, одного из инженеров Google, работающих на Android SDK:

Не используйте getBaseContext (), просто используйте контекст, который у вас есть.

Это было из сообщения в группе новостей разработчиков Android , вы можете подумать о том, чтобы задать свой вопрос там, потому что небольшая часть людей, работающих в Android, контролирует эту группу новостей и отвечает на вопросы.

Поэтому в целом предпочтительнее использовать глобальный контекст приложения, когда это возможно.

Вот что я нашел относительно использования context :

1). В рамках самого Activity используйте this для раздувания макетов и меню, регистрации контекстных меню, создания экземпляров виджета, запуска других действий, создания нового Intent в рамках Activity , создания экземпляров или других методов, доступных в 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() используйте 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 (например, ContentObserver) используйте подстановку Context, например:

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

Контекстная подстановка 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); } } } 

Inlined / Embedded 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() обычно используйте 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(); } } 

И, наконец, не используйте getBaseContext() как getBaseContext() разработчиками фреймворка Android.

UPDATE: добавьте примеры использования Context .

Я прочитал эту тему несколько дней назад, задавая себе тот же вопрос. Мое решение после прочтения было простым: всегда используйте applicationContext.

Однако у меня возникла проблема с этим, я потратил несколько часов, чтобы найти его, и несколько секунд, чтобы его решить … (меняя одно слово …)

Я использую LayoutInflater, чтобы раздуть представление, содержащее Spinner.

Итак, вот две возможности:

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

Что я заметил: если вы создали экземпляр linearLayout с помощью applicationContext, тогда, когда вы нажимаете на spinner в своей деятельности, у вас будет неперехваченное исключение, исходящее из виртуальной машины dalvik (а не из вашего кода, поэтому я потратил много Времени, чтобы найти, где была моя ошибка …).

Если вы используете baseContext, тогда все в порядке, откроется контекстное меню, и вы сможете выбрать один из своих вариантов.

Итак, вот мой вывод: я полагаю (я еще не тестировал его дальше), чем baseContext требуется при работе с contextMenu в вашей деятельности …

Тест был выполнен с использованием API 8 и протестирован на HTC Desire, Android 2.3.3.

Надеюсь, мой комментарий до сих пор вам не надоел, и желаю вам всего наилучшего. Счастливое кодирование 😉

Во-первых, я согласен с тем, что мы должны использовать appcontext, когда это возможно. Затем «это» в деятельности. У меня никогда не было необходимости в basecontext.

В моих тестах в большинстве случаев они могут быть взаимозаменяемы. В большинстве случаев причиной, по которой вы хотите получить контекст, является доступ к файлам, настройкам, базе данных и т. Д. Эти данные в конечном итоге отражаются как файлы в папке личных данных вашего приложения (/ data / data /). Независимо от того, какой контекст вы используете, они будут сопоставлены с одной и той же папкой / файлами, чтобы вы были в порядке.

Вот что я наблюдал. Возможно, есть случаи, когда вы должны их отличать.

В некоторых случаях вы можете использовать контекст Activity поверх контекста приложения при запуске чего-либо в потоке. Когда поток завершает выполнение, и вам нужно вернуть результат обратно к активности вызывающего, вам нужен этот контекст с обработчиком.

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

Простыми словами

getApplicationContext() поскольку предлагаемое имя метода позволит вашему приложению узнать о подробностях приложения, доступ к которым вы можете получить из любого места приложения. Таким образом, вы можете использовать это в привязке к сервису, регистрации вещания и т. Д. Application context будет активным до тех пор, пока приложение не выйдет.

getActivity() или this заставит ваше приложение узнать о текущем экране, который будет отображаться также на уровне уровня приложения, предоставляемом application context . Итак, что бы вы ни хотели узнать о текущем экране, таком как Window ActionBar Fragementmanger и поэтому доступны в этом контексте. В основном и Activity расширяют Context . Этот контекст будет живым до тех пор, пока не будет активен текущий компонент (активность)

Я использовал это и getBaseContext при поджаривании с onClick (очень зеленый noob для Java и Android). Я использую это, когда мой кликер находится непосредственно в getBaseContext и должен использовать getBaseContext в анонимном внутреннем клиенте. Я предполагаю, что это довольно трюк с getBaseContext , возможно, он возвращает контекст активности, в котором скрывается внутренний класс.