IT

검증되지 않은 예외 오류입니까?

lottoking 2020. 8. 13. 06:53
반응형

검증되지 않은 예외 오류입니까?


내 개발자 콘솔에서 사람들은 내가 가지고있는 어떤 전화 재현 할 수없는 오류를 계속보고합니다. 한 사람이 내 배터리 서비스의 설정 화면을 열려고하면 수 있습니다 메시지를 남겼습니다. 오류에서 알 수 없음 오류가 등록되지 않습니다.

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동일한 수신자에게 전화를 거는 횟수를 제어 할 수 없거나 제어하고 싶지 않다고 가정 ).


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.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) 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) at com.android.internal.os .ZygoteInit.main (ZygoteInit.java:696) 


다른 답변에서 언급했듯이에 대한 각 호출 registerReceiver이 정확히 하나의 호출과 일치하지 않기 때문에 예외가 발생 합니다 unregisterReceiver. 왜 안돼?

An ActivityonDestroy모든 onCreate호출에 대해 항상 일치하는 호출 있는 것은 아닙니다 . 시스템의 메모리가 부족하면을 호출하지 않고 앱이 제거 onDestroy됩니다.

풋하는 올바른 위치 registerReceiver호출은에 onResume전화하고, unregisterReceiveronPause. 이 통화 쌍은 항상 일치합니다. 자세한 내용은 활동 수명주기 다이어그램을 참조하세요. 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;
                }



        }

이 문제에 직면하고 제안 된 모든 것을 시도했지만 여전히 작동하지 않는 사람을 위해, 이것이 LocalBroadcastManager.getInstance(this).registerReceiver(...)내가 먼저 LocalBroadcastManager 유형의 지역 변수를 만든 대신 내 문제를 정렬 한 방법입니다 .

private LocalBroadcastManager lbman;

그리고이 변수를 사용하여 브로드 캐스트 리시버에서 등록 및 등록 해제를 수행합니다.

lbman.registerReceiver(bReceiver);

lbman.unregisterReceiver(bReceiver);

BR을 등록하는 UI 컴포넌트가 파괴되면 BR도 파괴됩니다. 따라서 코드가 등록 취소되면 BR이 이미 폐기되었을 수 있습니다.

참고 URL : https://stackoverflow.com/questions/6165070/receiver-not-registered-exception-error

반응형