ServiceConnectionLeaked in Android
Ich bin versucht, einen Dienst in Android für einige grundlegende Datenbank-Operationen, aber aus irgendeinem Grund bin ich immer eine Aktivität ausgetreten ServiceConnection Fehler. Ich poste die komplette Logcat Auslesen an der Unterseite.
Ich den gleichen service in mehreren Aktivitäten, so habe ich einen Superklasse erledigen alle service-Aufgaben. Es sieht wie folgt aus:
private MyInterface child;
public void onCreate(Bundle savedInstanceState, MyInterface child){
super.onCreate(savedInstanceState);
doBindService();
}
public void onResume(){
super.onResume();
doBindService();
}
protected void onPause(){
super.onPause();
doUnbindService();
}
private boolean bound;
private boolean binding;
ServiceConnection Connection = new ServiceConnection(){
//called when the service is connected
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(LOGTAG, "Bound to Service");
bound = true;
binding = false;
toServiceMessenger = new Messenger(service);
while(!commandsForService.isEmpty()){
sendToService(commandsForService.poll());
}
}
//called when the service is disconnected
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(LOGTAG, "Unboud from Service");
bound = false;
binding = false;
toServiceMessenger = null;
}
};
private boolean doBindService(){
Log.d(LOGTAG, "Attempting to Bind to Service");
if(!bound && !binding){
binding = true;
bindService(new Intent(this, global.FetchService.class), Connection, Context.BIND_AUTO_CREATE);
}
return bound;
}
private void doUnbindService(){
Log.d(LOGTAG, "Attempting to Unbind from Service");
if(bound && !binding){
binding = true;
unbindService(Connection);
}
}
public void sendToService(Message msg){
if(bound){
sendMessageToService(msg);
}
else{
commandsForService.add(msg);
}
}
private void sendMessageToService(Message msg){
if(bound){
msg.replyTo = fromServiceMessenger;
try {
toServiceMessenger.send(msg);
} catch (RemoteException e) {
Log.d(LOGTAG, "RemoteException communicating with service");
}
}
else{
Log.d(LOGTAG, "Error: toServiceMessenger null while bound");
}
}
Die Idee ist, dass das Kind Aktivität brauchen nie sorgen machen, dass mit dem Dienst verbunden sind oder nicht, die Oberklasse sollte sich darum kümmern, erste Daten der Dienst-und zurück zu dem Kind.
Den Logcat Punkte doBindService() in onCreate() --> bindService(new Intent(this, global.FetchService.class), Verbindung, Zusammenhang.BIND_AUTO_CREATE); wie in der Zeile den Fehler verursacht. Der Dienst wird jedoch nur Lecks, nachdem die Aktivität ausgeführt wurde und sichtbar für mehr als 15 Sekunden, also denke ich nicht, dass onCreate() sollte genannt worden.
Hier der Logcat:
09-02 09:25:40.635: E/ActivityThread(5963): Activity childActivity has leaked ServiceConnection superClass$1@42cb1b70 that was originally bound here
09-02 09:25:40.635: E/ActivityThread(5963): android.app.ServiceConnectionLeaked: Activity childActivity has leaked ServiceConnection superClass$1@42cb1b70 that was originally bound here
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1055)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:949)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.ContextImpl.bindService(ContextImpl.java:1472)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.ContextImpl.bindService(ContextImpl.java:1464)
09-02 09:25:40.635: E/ActivityThread(5963): at android.content.ContextWrapper.bindService(ContextWrapper.java:394)
09-02 09:25:40.635: E/ActivityThread(5963): at superClass.doBindService(FetchActivity.java:253)
09-02 09:25:40.635: E/ActivityThread(5963): at superClass.onCreate(FetchActivity.java:61)
09-02 09:25:40.635: E/ActivityThread(5963): at childActivity.onCreate(Showcase_Activity.java:37)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.Activity.performCreate(Activity.java:5066)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1101)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.ActivityThread.access$600(ActivityThread.java:151)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
09-02 09:25:40.635: E/ActivityThread(5963): at android.os.Handler.dispatchMessage(Handler.java:99)
09-02 09:25:40.635: E/ActivityThread(5963): at android.os.Looper.loop(Looper.java:155)
09-02 09:25:40.635: E/ActivityThread(5963): at android.app.ActivityThread.main(ActivityThread.java:5493)
09-02 09:25:40.635: E/ActivityThread(5963): at java.lang.reflect.Method.invokeNative(Native Method)
09-02 09:25:40.635: E/ActivityThread(5963): at java.lang.reflect.Method.invoke(Method.java:511)
09-02 09:25:40.635: E/ActivityThread(5963): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
09-02 09:25:40.635: E/ActivityThread(5963): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:795)
09-02 09:25:40.635: E/ActivityThread(5963): at dalvik.system.NativeStart.main(Native Method)
Jede Hilfe wird sehr geschätzt.
- Tut ServiceConnectionLeaked auftreten lassen, nachdem Sie den childActivity? Könnten Sie Log-Anweisungen sofort nach bindService und unbindService um sicherzustellen, dass Sie berufen sind, wie Sie passende Paare?
- Vielleicht versuchen Sie den Aufruf doUnbindService() vor dem Aufruf von super.onPause() (in der onPause () - Methode)?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie Ihr Sie nennt, die
doBindService()
imonCreate()
sollten Sie das tunUnbindService()
imonDestroy()
.Es funktioniert für mich.
Die Sie aufrufen
doBindService()
in beidenonCreate()
undonResume()
, versuchen, nennen es nur inonResume()
passend zu Ihrem AufrufdoUnbindService()
imonPause()
Müssen Sie die gute Referenz für die Aktivität
getActivity() liefert den aktuellen, und Sie brauchen, um die Bindung auf der einen, die das binden
hier, wie ich das problem behoben :
Sie diese Fehlermeldung bekommen, weil die Dienstleistungen, die Sie binden, die mit der Tätigkeit ist nicht beendet, wenn die Aktivität zerstört. Damit durch diese Ihr service ist immer noch vorhanden in den Speicher und Ressourcen verbrauchen, die nichts zu tun.
Dieses problem zu lösen, rufen Sie
doBindService()
imonCreate()
unddoUnbindService()
imonDestroy()
Dieses Problem beschränkt sich auf Android SDKs vor Android O, API level 26. In Android O folgende Funktion zu starten Vordergrund services eingeführt wurde
ContextCompat.startForegroundService(...)
im Gegensatz zucontext.startService(...)
. Die älteren APIs bedienen Sie nicht die Vorder-lifecycle, so ist die Notwendigkeit zu nennencontext?.unbindService(serviceConnection)
imonDestroy(...)
.Die neue Methode stellt sicher müssen Entwickler erstellen eine Benachrichtigung mit
startForeground(notificationId, notification)
innerhalb von fünf Sekunden aufrufenContextCompat.startForegroundService(...)
um sicherzustellen, dass dem Benutzer bewusst ist, die die Vorder-Dienst ausgeführt werden, auch wenn die app ist nicht in Sicht.Für alle Geräte mit Nougat API level 25 oder niedriger stellen Sie sicher, trennen Sie den Dienst manuell.
ie