wake-up-neo.com

Android Java.lang.IllegalArgumentException: Dienst nicht registriert

Ich habe ein Setup, das ungefähr so ​​aussieht:

class MyFragment implements SomeEventListener {

    Application mAppContext;    

    boolean mBound;
    boolean mDidCallUnbind;
    MyIBinder mBinder;
    ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBound = true;
            mBinder = (MyIBinder) service;
            mBinder.getThings();...
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mDidCallUnbind = false;
            mBound = false;
            mBinder = null;
        }
    };

    ...

    @Override
    public void onSomeEvent() {
        mAppContext.bindService(...);
    }

    void unbindService() {
        if (mBound && !mDidCallUnbind) {
            mDidCallUnbind = true;
            mAppContext.unbindService(mConnection);
        }
    }

    @Override
    public void onPause() {
        unbindService();
        super.onPause();
    }
}

Von Zeit zu Zeit sehe ich jedoch immer noch den Fehler im Titel: Java.lang.IllegalArgumentException: Service not registered Wird generiert, wenn unbindService() aufgerufen wird. Fehlt mir etwas Dummes oder ist noch mehr los? Ich möchte darauf hinweisen, dass möglicherweise mehr als ein Fragment desselben vorhanden ist.

Bearbeiten

Da anscheinend niemand den Code liest, lass es mich erklären. unbindService() ruft Context.unbindService(ServiceConnection) nur auf, wenn der Dienst gebunden ist (mBound) nd zuvor nicht vor der onServiceDisconnected(...) Rückruf wurde von einem möglichen vorherigen Aufruf von unbindService() getroffen.

In Anbetracht dessen, gibt es Fälle, in denen Android) Ihren Dienst für Sie aufhebt, sodass der Dienst nicht mehr gebunden wird, aber onServiceDisconnected nicht aufgerufen wird, wodurch ich in einem abgestandenen Zustand bin?

Außerdem verwende ich meinen Anwendungskontext, um die anfängliche Bindung durchzuführen. Angenommen, etwas wie:

@Override
public void onCreate() {
    mApplication = getContext().getApplicationContext();
}
36
dcow

Mir ist klar, dass diese Frage bereits beantwortet wurde. Aber ich denke, es gibt Gründe, warum die Leute diesen Fehler machen.

Das Problem liegt wirklich in den Schulungsunterlagen. http://developer.Android.com/reference/Android/app/Service.html zeigt eine korrekte Implementierung während https://developer.Android.com/guide/components/bound) -services.html im 'ActivityMessenger' zeigt eine sehr [~ # ~] falsche [~ # ~] Implementierung.

Im 'ActivityMessenger'-Beispiel könnte onStop () möglicherweise aufgerufen werden, bevor der Dienst tatsächlich gebunden wurde.

Der Grund für diese Verwirrung ist, dass sie den Booleschen Wert für gebundenen Service verwenden, um in verschiedenen Beispielen unterschiedliche Bedeutungen zu haben. (hauptsächlich wurde bindService () OR ist der Dienst tatsächlich verbunden) genannt

In den richtigen Beispielen, in denen die Aufhebung der Bindung () basierend auf dem Wert des gebundenen Booleschen Werts erfolgt, gibt der gebundene Boolesche Wert an, dass der bindService () aufgerufen wurde. Da es für die Ausführung des Hauptthreads in der Warteschlange steht, muss unbindService () aufgerufen werden (damit es ausgeführt werden kann), unabhängig davon, wann (falls überhaupt) onServiceConnected () ausgeführt wird.

In anderen Beispielen, wie in http://developer.Android.com/reference/Android/app/Service.html . Die Bindung gibt an, dass die Dienste tatsächlich gebunden sind, sodass Sie sie verwenden und keine NullPointerException abrufen können. Beachten Sie, dass in diesem Beispiel der Aufruf von unbindService () weiterhin ausgeführt wird und der gebundene Boolesche Wert nicht bestimmt, ob die Bindung aufgehoben werden soll oder nicht .

16
aaronvargas

Verwenden Sie mIsBound in doBindService() und doUnbindService() anstatt in der Instanz ServiceConnection.

ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mBinder = (MyIBinder) service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mBinder = null;
    }
}; 

...

public void doBindService() {
    bindService(new Intent(this, MyService.class),
        mConnection, Context.BIND_AUTO_CREATE);
    mIsBound = true;
}

public void doUnbindService() {
    if (mIsBound) {
        unbindService(mConnection);
        mIsBound = false;
    }
}

Dies geschieht in http://developer.Android.com/reference/Android/app/Service.html

25
Jacob Phillips

Java.lang.IllegalArgumentException: Service not registered Bedeutet, dass Sie nicht an den Dienst gebunden waren, als unbindService() aufgerufen wurde.

In Ihrem Fall wurde onSomeEvent() nie vor dem Aufruf von unbindService() in onPause() aufgerufen.

8
pelotasplus

Ein weiterer möglicher Grund für diese Ausnahme könnte sein, dass unbindService vom falschen Context aufgerufen wird. Da Dienste nicht nur an Aktivitäten gebunden sein können, sondern auch an andere Instanzen, die von Context (mit Ausnahme von BroadcastReceivers) geerbt wurden, und zwar auch von anderen Diensten, müssen Sie sicherstellen, dass unbindService vom Kontext aufgerufen wird das hat den Service und nicht durch den gebundenen Service selbst gebunden. Dies würde direkt zu der obigen Ausnahme "Dienst nicht registriert" führen.

Grund?

Wenn in Ihrer Aktivität unbindService () vor bindService () aufgerufen wird, erhalten Sie dieses IllegalArgumentException.

Wie vermeide ich es?
Es ist einfach. Sie würden kein Boolesches Flag benötigen, wenn Sie den Dienst in dieser Reihenfolge binden und entbinden.

Lösung 1:

Binden Sie in onStart() und lösen Sie in onStop()

Your Activity {

    @Override
    public void onStart()
    {
        super.onStart();
        bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onStop()
    {
        super.onStop();
        unbindService(mConnection);
    }

 } 

Lösung 2:
In onCreate() binden und in onDestroy() binden

 Your Activity {

    @Override
    public void onCreate(Bindle sis)
    {
        super.onCreate(sis);
        ....
        bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        unbindService(mConnection);
    }         

 }

Relevanter Link:

Android offizielle Dokumentation schlägt vor das
Wenn Sie mit dem Dienst nur interagieren müssen, während Ihre Aktivität sichtbar ist , wählen Sie Lösung1 .
Wenn Sie möchten, dass Ihre Aktivität auch im angehaltenen Hintergrund Antworten erhält, wählen Sie ) Lösung2 .

0
Rohit Singh

Ich habe genau das gleiche Problem mit meiner Bewerbung. Hin und wieder bekomme ich IllegalArgumentException. Ich vermute, der Sonderfall liegt vor, wenn der Dienst nicht gebunden ist und onPausevoronServiceDisconnected heißt. Also würde ich Synchronized Dinge versuchen, um die korrekte Ausführung sicherzustellen.

0
slott