내 개발자 콘솔에서 사람들은 내가 가지고있는 어떤 전화에서도 재현 할 수없는 오류를 계속보고합니다. 한 사람이 내 배터리 서비스의 설정 화면을 열려고하면받을 수 있다는 메시지를 남겼습니다. 오류에서 알 수 있듯이 수신자가 등록되지 않았 음을 나타냅니다.
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 : FATAL EXCEPTION : main Process : com.jialan.guangdian.view, PID : 19064 java.lang.RuntimeException : Unable to stop service com.google.android.exoplayer.demo.player.PlayService@141ba331 : java.lang.IllegalArgumentException : 수신기가 등록되지 않음 : 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) at 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 : 수신기가 등록되지 않음 : 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) at 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) 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) at java.lang.reflect.Method.invoke (Method.java:372) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java :901) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:696)
답변
unregisterReceiver에 대해 모든 곳에서이 코드를 사용하십시오.
if (batteryNotifyReceiver != null) {
unregisterReceiver(batteryNotifyReceiver);
batteryNotifyReceiver = null;
}
답변
다른 답변에서 언급했듯이에 대한 각 호출 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);
}
답변
편집 : 이것은 inazaruk 및 electrichead에 대한 대답입니다 … 나는 그들과 비슷한 문제를 겪었고 다음을 발견했습니다 …
이 문제에 대한 오랜 버그가 있습니다. 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 ()에 등록 및 등록 해제 메소드를 넣습니다.
@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;
}
}