Один случай - когда Вы пробуете к коду модульного теста, который использует WeakReference.
Несмотря на то, что Дэвид Уэссер дал отличный ответ, я думаю, что есть еще важная информация, которую нужно добавить. Итак, здесь говорится:
В конце концов, Context - это просто ссылка на различные компоненты вашего собственного приложения (такие как ресурсы, информация о пакете и т. Д.) И на внешнюю операционную систему. Таким образом, все различные контексты, которые вы упомянули, являются просто ссылкой на одну и ту же вещь, единственная разница в том, как долго каждая ссылка действительна.
В конкретном случае AppWidgetProvider контекст, который вы получаете для его методов, является тем же контекстом, который предоставляется BroadcastReceiver методом onReceive. На самом деле AppWidgetProvider - это просто необычное имя для обычного BroadcastReceiver , который вызывает определенные методы при получении намерений, связанных с виджетами, например ACTION_APPWIDGET_UPDATE .
Проблема с вашим кодом заключается в том, что AppWidgetProvider имеет очень короткий жизненный цикл: каждый раз, когда поступает трансляция виджета, создается новый экземпляр AppWidgetProvider только для выполнения соответствующего метода. Поэтому, когда вы делаете это:
context.getApplicationContext.registerReceiver(this, intentName);
вы регистрируете новый BroadcastReceiver в контексте вашего приложения каждый раз, когда принимается намерение виджета. Кроме того, когда вы пытаетесь отменить регистрацию вашего AppWidgetProvider , вы на самом деле ссылаетесь на другой его экземпляр, поэтому вы, вероятно, получите исключение, и даже если вы его поймаете, в вашем приложении будет утечка памяти .
Поэтому, если вам нужно программно добавить фильтры намерений в BroadcastReceiver , вот мое предложение:
1) Создайте другой BroadcastReceiver в классе долгоживущих контекстов , как класс, который расширяет приложение. Давайте назовем это mMainReceiver .
2) Примените фильтр намерений к нему программно, зарегистрируйте и отмените его регистрацию в соответствии с вашими потребностями.
3) Создайте частное намерение, например MY_ACTION_TIME_TICKER , и запустите его из вашего mMainReceiver метода onReceive.
4) В своем манифесте зарегистрируйте фильтр MY_ACTION_TIME_TICKER на своем приемнике AppWidgetProvider.
Таким образом, у вас может быть один BroadcastReceiver, действующий как мост к вашему AppWidgetProvider, и вы можете зарегистрировать и отменить его регистрацию в любое время.