私の開発者コンソールでは、私が持っているどの電話でも再現できないエラーを報告し続けています。ある人は、私のバッテリーサービスの設定画面を開こうとするとメッセージが表示されるというメッセージを残しました。エラーからわかるように、レシーバーが登録されていないと表示されます。
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.access$3900(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);
}
}
なぜ彼らはそのエラーを取得するのでしょうか?
問題の根本は次の場所にあります。
unregisterReceiver(batteryNotifyReceiver);
受信者が既に登録解除されている場合(おそらくこの投稿に含まれていないコードで)または登録されていない場合は、unregisterReceiver
を呼び出してIllegalArgumentException
をスローします。あなたの場合、この例外に特別なtry/catchを入れて無視する必要があります(同じレシーバーでunregisterReceiver
を呼び出す回数を制御できない、または制御したくない場合)。
で登録するときは注意してください
LocalBroadcastManager.getInstance(this).registerReceiver()
で登録を解除することはできません
unregisterReceiver()
あなたは使わなければなりません
LocalBroadcastManager.getInstance(this).unregisterReceiver()
またはアプリがクラッシュします。次のようにログインします。
09-30 14:00:55.458 19064-19064/com.jialan.guangdian.view E/AndroidRuntime:致命的な例外:メインプロセス:com.jialan.guangdian.view、PID:19064 Java.lang.RuntimeException:サービスを停止できませんcom.google.Android.exoplayer.demo.player.PlayService@141ba331:Java.lang.IllegalArgumentException:Receiver not registered:com.google.Android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 at Android.app.ActivityThread。 handleStopService(ActivityThread.Java:2941)at Android.app.ActivityThread.access $ 2200(ActivityThread.Java:148)at Android.app.ActivityThread $ H.handleMessage(ActivityThread.Java:1395)at Android.os.Handler.dispatchMessage( Handler.Java:102)at Android.os.Looper.loop(Looper.Java:135)at Android.app.ActivityThread.main(ActivityThread.Java:5310)at Java.lang.reflect.Method.invoke(Native Method) Java.lang.reflect.Method.invoke(Method.Java:372)at com.Android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.Java:901)at com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:696)原因:Java.lang.IllegalArgumentException:Receiver not registered:com.google.Android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 at Android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.Java: 769)at Android.app.ContextImpl.unregisterReceiver(ContextImpl.Java:1794)Android.content.ContextWrapper.unregisterReceiver(ContextWrapper.Java:510)at com.google.Android.exoplayer.demo.player.PlayService.onDestroy(PlayService .Java:542)at Android.app.ActivityThread.handleStopService(ActivityThread.Java:2924)at Android.app.ActivityThread.access $ 2200(ActivityThread.Java:148)at Android.app.ActivityThread $ H.handleMessage(ActivityThread.Java :1395)Android.os.Handler.dispatchMessage(Handler.Java:102)Android.os.Looper.loop(Looper.Java:135)Android.app.ActivityThread.main(ActivityThread.Java:5310)Java .lang.reflect.Method.invoke(Native Method)at Java.lang.reflect.Method.invoke(Method.Java:372)at com.Android.internal.os.Zygo com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:696)のteInit $ MethodAndArgsCaller.run(ZygoteInit.Java:901)
UnregisterReceiverにはどこでも次のコードを使用します。
if (batteryNotifyReceiver!=null) {
unregisterReceiver(batteryNotifyReceiver);
batteryNotifyReceiver=null;
}
他の回答で述べたように、registerReceiver
への各呼び出しはunregisterReceiver
への1回の呼び出しと一致しないため、例外がスローされます。何故なの?
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);
}
この問題には長年のバグがあります: http://code.google.com/p/Android/issues/detail?id=6191
Android 2.1から始まり、それ以降Android 2.xリリースのすべてに存在しているようです。ただし、Android 3.xまたは4.xの問題であるかどうかはわかりません。
とにかく、この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();
}
}
}
レシーバをnullとして宣言してから、アクティビティのonResume()およびonPause()にそれぞれregisterおよびunregisterメソッドを配置します。
@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;
}
}
この問題に遭遇し、提案されたすべてを試してもまだ何も動作しない人のために、これはLocalBroadcastManager.getInstance(this).registerReceiver(...)
を実行する代わりに私の問題をソートする方法です。
private LocalBroadcastManager lbman;
そして、この変数を使用して、broadcastreceiverで登録と登録解除を実行しました。
lbman.registerReceiver(bReceiver);
そして
lbman.unregisterReceiver(bReceiver);
BRを登録するUIコンポーネントが破壊されると、BRも破壊されます。したがって、コードが登録解除されると、BRはすでに破棄されている可能性があります。