2012-04-29 16 views
15

Ich habe ein Szenario, in dem eine Aktivität einen Dienst durch Aufruf der startService-Methode startet: Sowohl Activity als auch Service sind im selben Paket enthalten. Dann könnte der Dienst gemäß seinen Konfigurationsparametern eine Aktivität starten (nennen wir sie ExternalActivity), die in einem anderen Paket enthalten ist: Diese Aktivität bindet den Dienst durch bindService; sobald diese Tätigkeit seine Aufgaben beendet hat, ruft sie die unbindService Methode wie folgt ...Verhindern, dass ein Android-Dienst nach einer Freigabe zerstört wird

// method of ExternalActivity 
@Override 
public void onDestroy() { 
    super.onDestroy(); 
    unbindService(...); 
} 

Als Folge wird der Dienst auch zerstört. Gibt es die Möglichkeit, die Zerstörung des Dienstes zu vermeiden?

+0

Nach dem [dev guide] (http://developer.android.com/guide/topics/fundamentals/bound-services.html): * * Ein gebundener Dienst wird zerstört, sobald alle Clients die Verbindung getrennt haben, es sei denn, der Dienst wurde ebenfalls gestartet. ** Stoppen Sie ihn manuell in der onUnbind() -Methode? – yorkw

+0

@Yorkw: Mein Dienst implementiert nicht "onUnbind" -Methode. – enzom83

Antwort

10

Als Folge wird der Dienst auch zerstört.

Wie yorkw erläutert, wird ein Dienst nur zerstört, wenn beide der folgenden Bedingungen erfüllt sind:

  1. Alle Anrufe zu bindService() durch entsprechende Anrufe unbindService() angepasst wurden.

  2. Wenn jemand startService() genannt, jemand auch stopService() oder der Dienst stopSelf() genannt genannt.

Gibt es die Möglichkeit, die Zerstörung des Dienstes zu vermeiden?

Finden Sie eine bessere Zeit stopService() oder stopSelf() zu nennen, je nachdem, was von denen, die Sie verwenden.

+1

Ich rufe 'stopService' nur manuell an, wenn ich auf einen Button der Aktivität klicke, die den Dienst startet. Der Dienst wird jedoch zerstört, wenn "ExternalActivity" (die einzige Anwendung, die den Dienst bindet) "unbindService" aufruft. – enzom83

+0

@ enzom83: So, es funktioniert richtig. Groß! Es ist sehr wichtig, dass Ihr Dienst heruntergefahren wird, wenn er nicht mehr benötigt wird. Wenn der Benutzer ausdrücklich einen Knopf gedrückt hat, um zu sagen, dass er den Dienst nicht mehr benötigt, respektieren Sie bitte seine Wünsche. Andernfalls werden sie dich mit Aufgabenmördern angreifen und von den Einstellungen anhalten, und das wird dir nicht gefallen. – CommonsWare

+2

Ich habe die Fehlfunktion behoben, indem ich die Methode 'onStartCommand' überschrieben habe, so dass jetzt 'START_STICKY' zurückgegeben wird. – enzom83

1

Was ist damit?

public class MainActivity extends Activity { 

private LocalService mBoundService; 
private boolean mIsBound; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    if (LocalService.isRunning()) 
     doBindService(false); 

    Button startService = (Button) findViewById(R.id.startService); 
    startService.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      doBindService(true); 
     } 
    }); 
    Button stopService = (Button) findViewById(R.id.stopService); 
    stopService.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      doUnbindService(true); 
     } 
    }); 
} 

void doBindService(boolean start) { 

    Intent i = new Intent(this, LocalService.class); 
    if (start) 
     startService(i); 
    bindService(i, mConnection, Context.BIND_AUTO_CREATE); 

    mIsBound = true; 
} 

void doUnbindService(boolean stop) { 
    if (mIsBound) { 
     // Detach our existing connection. 
     unbindService(mConnection); 
     if (stop) 
      stopService(new Intent(this, LocalService.class)); 
     mIsBound = false; 
    } 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    doUnbindService(false); 
} 

private ServiceConnection mConnection = new ServiceConnection() { 
    public void onServiceConnected(ComponentName className, IBinder service) { 

     mBoundService = ((LocalService.LocalBinder) service).getService(); 

     // Tell the user about this for our demo. 
     Toast.makeText(MainActivity.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); 
    } 

    public void onServiceDisconnected(ComponentName className) { 

     mBoundService = null; 
     Toast.makeText(MainActivity.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); 
    } 
}; 

} 

LocalService.java von https://developer.android.com/reference/android/app/Service.html#LocalServiceSample

public class LocalService extends Service { 

... 
private static boolean isRunning=false; 
... 

@Override 
public void onCreate() { 
    mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 
    L.i("Service.onCreate() "); 
    // Display a notification about us starting. We put an icon in the status bar. 
    showNotification(); 
    isRunning = true; 

} 

@Override 
public void onDestroy() { 
    // Cancel the persistent notification. 
    mNM.cancel(NOTIFICATION); 
    isRunning = false; 
    // Tell the user we stopped. 
    Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); 
} 
... 

public static boolean isRunning() 
{ 
    return isRunning; 
} 
} 
Verwandte Themen