Приемник не зарегистрирован ошибка?
в моей консоли разработчика люди продолжают сообщать об ошибке, которую я не могу воспроизвести на любом телефоне, который у меня есть. Один человек оставил сообщение о том, что он получает его, когда они пытаются открыть экран настроек моей службы батареи. Как вы можете видеть из ошибки он говорит, что приемник не зарегистрирован.
java.lang.RuntimeException: Unable to stop service .BatteryService@4616d688: java.lang.IllegalArgumentException: Receiver not registered: com.app.notifyme.BatteryService$BatteryNotifyReceiver@4616d9d0
at android.app.ActivityThread.handleStopService(ActivityThread.java:3164)
at android.app.ActivityThread.access00(ActivityThread.java:129)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2173)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4701)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Receiver not registered:com..BatteryService$BatteryNotifyReceiver@4616d9d0
at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:805)
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:859)
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)
at com.app.notifyme.BatteryService.onDestroy(BatteryService.java:128)
at android.app.ActivityThread.handleStopService(ActivityThread.java:3150)
я регистрируюсь в моем onCreate
@Override
public void onCreate(){
super.onCreate();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(batteryNotifyReceiver,filter);
pref.registerOnSharedPreferenceChangeListener(this);
}
отменить регистрацию в onDestroy, а также с предпочтениями слушателя
@Override
public void onDestroy(){
super.onDestroy();
unregisterReceiver(batteryNotifyReceiver);
}
и это мой приемник в сервис
private final class BatteryNotifyReceiver extends BroadcastReceiver {
boolean connected;
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor edit = prefs.edit();
updatePreferences(prefs);
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)){
connected = true;
}else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)){
connected = false;
}else if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){
if(level < lastLevel){
if(level > 40){
edit.putBoolean("first", false).commit();
edit.putBoolean("second", false).commit();
edit.putBoolean("third", false).commit();
edit.putBoolean("fourth",false).commit();
edit.putBoolean("fifth", false).commit();
}
if(level == 40){
if(!first){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("first", true).commit();
}
}else if(level == 30){
if(!second){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("second", true).commit();
}
}else if(level == 20){
if(!third){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("third", true).commit();
}
}else if(level == 15){
if(!fourth){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("fourth", true).commit();
}
}else if(level == 5){
if(!fifth){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("fifth", true).commit();
}
}
lastLevel = temp;
}
}
Intent i = new Intent(context,BatteryNotifyReceiver.class);
context.startService(i);
}
}
есть идеи, почему они будут получать эту ошибку?
9 ответов:
корень вашей проблемы находится здесь:
unregisterReceiver(batteryNotifyReceiver);
если получатель уже был незарегистрирован (вероятно, в коде, который вы не включили в этот пост) или не был зарегистрирован, то позвоните в
unregisterReceiver
закидываемIllegalArgumentException
. В вашем случае вам нужно просто поставить специальный try / catch для этого исключения и игнорировать его (предполагая, что вы не можете или не хотите контролировать количество вызововunregisterReceiver
на том же recevier).
используйте этот код везде для unregisterReceiver:
if (batteryNotifyReceiver!=null) { unregisterReceiver(batteryNotifyReceiver); batteryNotifyReceiver=null; }
будьте осторожны, когда вы регистрируетесь по
LocalBroadcastManager.getInstance(this).registerReceiver()
вы не можете отменить регистрацию по
unregisterReceiver()
вы должны использовать
LocalBroadcastManager.getInstance(this).unregisterReceiver()
или приложение рухнет, войдите в систему следующим образом:
09-30 14:00:55.458 19064-19064/com.jialan.guangdian.просмотр E / AndroidRuntime: фатальное исключение: main Процесс: ком.jialan.guangdian.вид, PID: 19064 Ява.ленг.RuntimeException: не удается остановить службу com.гуглить.андроид.экзопласт.демонстрация.игрок.PlayService@141ba331: java.ленг.IllegalArgumentException: приемник не зарегистрирован: com.гуглить.андроид.экзопласт.демонстрация.игрок.PlayService$PlayStatusReceiver@19538584 на Андроид.приложение.ActivityThread.handleStopService (ActivityThread.java: 2941) на Андроид.приложение.ActivityThread.доступ$2200(ActivityThread.Ява:148) на Андроид.приложение.ActivityThread$H. handleMessage (ActivityThread.java:1395) на Андроид.ОС.Обработчик.dispatchMessage(обработчика.Ява:102) на Андроид.ОС.Петлитель.петля(Looper.java:135) на Андроид.приложение.ActivityThread.main (ActivityThread.java: 5310) на Яве.ленг.отражать.Метод.invoke(собственный метод) на Яве.ленг.отражать.Метод.метод Invoke.java: 372) на com.андроид.внутренний.ОС.ZygoteInit$MethodAndArgsCaller.беги(Зиготеинит.java:901) на ком.андроид.внутренний.ОС.Зиготеинит.главный(Зиготеинит.java:696) Вызвано: java.ленг.IllegalArgumentException: приемник не зарегистрирован: com.гуглить.андроид.экзопласт.демонстрация.игрок.PlayService$PlayStatusReceiver@19538584 на Андроид.приложение.Заряженный АПК.forgetReceiverDispatcher (LoadedApk.java:769) на Андроид.приложение.ContextImpl.unregisterReceiver (ContextImpl.java: 1794) на Андроид.содержание.ContextWrapper.unregisterReceiver(ContextWrapper.java:510) на ком.гуглить.андроид.экзопласт.демонстрация.игрок.PlayService.onDestroy(PlayService.java: 542) на Андроид.приложение.ActivityThread.handleStopService (ActivityThread.java: 2924) на Андроид.приложение.ActivityThread.доступ$2200(ActivityThread.Ява:148) на андроид.приложение.ActivityThread$H. handleMessage (ActivityThread.java:1395) на Андроид.ОС.Обработчик.dispatchMessage(обработчика.Ява:102) на Андроид.ОС.Петлитель.петля(Looper.java:135) на Андроид.приложение.ActivityThread.main (ActivityThread.java: 5310) на Яве.ленг.отражать.Метод.invoke(собственный метод) на Яве.ленг.отражать.Метод.метод Invoke.java: 372) на ком.андроид.внутренний.ОС.ZygoteInit$MethodAndArgsCaller.беги(Зиготеинит.java:901) на com.андроид.внутренний.ОС.Зиготеинит.главный(Зиготеинит.java: 696)
как уже упоминалось в других ответах, исключение создается, потому что каждый вызов
registerReceiver
не соответствует точно один вызовunregisterReceiver
. Почему бы и нет?An
Activity
не всегда соответствуетonDestroy
вызов для каждогоonCreate
звонок. Если в системе заканчивается память, ваше приложение выселяется без вызоваonDestroy
.правильное место, чтобы поставить
registerReceiver
вызов вonResume
звонок, иunregisterReceiver
наonPause
. Эта пара вызовов всегда совпадает. Дополнительные сведения см. в диаграмме жизненного цикла действия. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycleваш код изменится следующим образом:
SharedPreferences mPref IntentFilter mFilter; @Override public void onCreate(){ super.onCreate(); mPref = PreferenceManager.getDefaultSharedPreferences(this); mFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_POWER_CONNECTED); filter.addAction(Intent.ACTION_POWER_DISCONNECTED); } @Override public void onResume() { registerReceiver(batteryNotifyReceiver,mFilter); mPref.registerOnSharedPreferenceChangeListener(this); } @Override public void onPause(){ unregisterReceiver(batteryNotifyReceiver, mFilter); mPref.unregisterOnSharedPreferenceChangeListener(this); }
EDIT: это ответ для inazaruk и electrichead... Я столкнулся с аналогичной проблемой для них и узнал следующее...
существует давняя ошибка для этой проблемы здесь:http://code.google.com/p/android/issues/detail?id=6191
похоже, что это началось вокруг Android 2.1 и присутствовало во всех Android 2.х релизах так. Я не уверен, что это все еще проблема в Android 3.x или 4.хотя Икс.
в любом случае, это Сообщение StackOverflow объясняет, как правильно обойти проблему (это не выглядит актуальным по URL, но я обещаю, что это так)
я использовал блок try - catch для временного решения проблемы.
// Unregister Observer - Stop monitoring the underlying data source. if (mDataSetChangeObserver != null) { // Sometimes the Fragment onDestroy() unregisters the observer before calling below code // See <a>http://stackoverflow.com/questions/6165070/receiver-not-registered-exception-error</a> try { getContext().unregisterReceiver(mDataSetChangeObserver); mDataSetChangeObserver = null; } catch (IllegalArgumentException e) { // Check wether we are in debug mode if (BuildConfig.IS_DEBUG_MODE) { e.printStackTrace(); } } }
объявите receiver как null, а затем поместите методы register и unregister в onResume() и onPause() действия соответственно.
@Override protected void onResume() { super.onResume(); if (receiver == null) { filter = new IntentFilter(ResponseReceiver.ACTION_RESP); filter.addCategory(Intent.CATEGORY_DEFAULT); receiver = new ResponseReceiver(); registerReceiver(receiver, filter); } } @Override protected void onPause() { super.onPause(); if (receiver != null) { unregisterReceiver(receiver); receiver = null; } }
когда компонент пользовательского интерфейса, который регистрирует BR, уничтожается, так же как и BR. Поэтому, когда код добирается до отмены регистрации, BR, возможно, уже был уничтожен.
для всех, кто столкнется с этой проблемой, и они попробовали все, что было предложено, и ничего не работает, вот как я отсортировал свою проблему, вместо того, чтобы делать
LocalBroadcastManager.getInstance(this).registerReceiver(...)
Сначала я создал локальную переменную типа LocalBroadcastManager,private LocalBroadcastManager lbman;
и использовал эту переменную для выполнения регистрации и отмены регистрации на broadcastreceiver, то есть
lbman.registerReceiver(bReceiver);
и
lbman.unregisterReceiver(bReceiver);
Comments