Ich habe die documentation about Bound Services gelesen, wo gezeigt wird, dass man leicht durch Nachrichten von einer Aktivität zu einem entfernten (dh nicht im gleichen Kontext) Service kommunizieren kann, aber ist es eine Möglichkeit Nachrichten aus dem Dienst senden an die gebunden Aktivität? Zum Beispiel ist meine Aktivität an einen laufenden Hintergrunddienst der gleichen Anwendung gebunden, sendet eine Nachricht an sie und beim Empfang dieser Nachricht antwortet der Dienst mit einer Nachricht an die Aktivität. Wie implementiere ich das? Kannst du mich auf eine Dokumentation verweisen, die dieses Thema erklärt?Wie kann ein Remote-Dienst Nachrichten an eine gebundene Aktivität senden?
Antwort
Gefundenes Beispiel in der Referenzdokumentation unter Remote Messenger Service Sample.
HINWEIS: Dies ist nur für In-Process-Dienste und Aktivitäten, nicht remote wie Frage gestellt.
Um einen Dienst mit einer Aktivität zu kommunizieren, müssen Sie einen Listener erstellen, den Sie von der Aktivität an den Dienst übergeben können.
Sie müssen einen Dienst erstellen, der an eine Aktivität gebunden ist.
Der erste Schritt besteht darin, einen Service zu machen. Stellen Sie im Service sicher, dass Sie ein Binder-Objekt und die Methode zum Zurückgeben eines Binderobjekts haben. Im Folgenden finden Sie ein Beispiel, das ich in meinem Dienst verwendet habe, um meinen Ordner abzurufen. Beachten Sie außerdem, dass dieser Binder über eine Methode zum Festlegen eines Listeners verfügt, die im Service als BoundServiceListener-Typenfeld gespeichert wird.
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class DownloadBgBinder extends Binder {
public DownloadBgService getService() {
// Return this instance of LocalService so clients can call public methods
return DownloadBgService.this;
}
public void setListener(BoundServiceListener listener) {
mListener = listener;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
Jetzt müssen Sie irgendeine Art von Oberfläche erstellen, die Sie an das Bindemittel-Objekt übergeben können, die Ihren Dienst, um Updates senden können. Unten ist mein BoundServiceListener.
public interface BoundServiceListener {
public void sendProgress(double progress);
public void finishedDownloading();
}
Jetzt müssen Sie in Ihrer Aktivität ein ServiceConnection-Objekt erstellen, das zum Binden an einen Service verwendet wird. Fügen Sie so etwas hinzu.
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
DownloadBgBinder binder = (DownloadBgBinder) service;
mService = binder.getService();
binder.setListener(new BoundServiceListener() {
@Override
public void sendProgress(double progress) {
// Use this method to update our download progress
}
@Override
public void finishedDownloading() {
}
});
mBound = true;
}
Nun ist die wichtige Linie hier zu bemerken ist
binder.setListener(new BoundServiceListener() {
@Override
public void sendProgress(double progress) {
// Use this method to update our download progress
}
@Override
public void finishedDownloading() {
}
});
Dieser Teil ist, wo ich eigentlich bin meine BoundServiceListener Schnittstelle zum Serviceklasse zu senden. Die Service-Klasse verwendet dann das Listener-Objekt hier
if (mListener!=null)
mListener.finishedDownloading();
if (mListener!=null)
mListener.sendProgress(percent);
Jetzt können Sie diese müssen Sie in Ihrer Serviceklasse überall setzen, und Ihre Aktivitäten werden Ihre Fortschritte Update erhalten.
Achten Sie auch darauf, dass Sie in Ihrer Aktivität Folgendes angeben, um den Dienst zu binden und zu starten.
Denken Sie daran, dass, obwohl Sie an einen Dienst binden, es tatsächlich nicht gestartet wird, bis Sie den Dienst starten. Die Bindung an den Dienst verbindet den Dienst nur mit einer Aktivität.der Startservice() -Methode ruft die Dienste
onStartCommand(Intent intent, int flags, int startId)
auch Ihren Dienst in Ihrem Manifest
<service android:name=".services.DownloadBgService" />
Auch unbind den Dienst erklären, wenn die Aktivität von
verläßt@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
Hoffnung, das hilft.
Tolles Beispiel, vielen Dank, dass Sie so viel Zeit damit verbracht haben, das Konzept zu erklären. –
@Danuofr dies funktioniert in-Prozess. Gibt es eine Möglichkeit, einen beliebigen Listener über Prozessgrenzen hinweg zu senden? – dcow
Nur Problem mit dieser Antwort ist: Es ist nur für einen lokalen Dienst. Aber die Frage wird klar gefragt, wie man das mit einem Remote-Service macht. Aber danke, dass du das aufgeschrieben hast. Aber vielleicht beachten Sie, dass dies nicht die Antwort auf die echte Frage ist :) –
Gibt es Situationen in der realen Welt, in denen wir eine Remotedienstbindung benötigen? –