Wie kann ich von einem Hintergrund Service-Informationen in einer Android-Aktivität aktualisieren
-
20-09-2019 - |
Frage
Ich versuche, eine einfache Android-Anwendung zu erstellen, die eine ActivityList von Informationen hat, wenn die Anwendung gestartet, ich plane, einen Dienst zu starten, die ständig die Daten der Berechnung werden (es wird sich ändern) und ich möchte die ActivityList sein synchron mit den Daten, dass der Dienst für das Leben des App berechnet wird.
Wie kann ich meine Aktivität einrichten, um auf den Service zuhören? Ist dies der beste Weg, um dieses Problem zu nähern?
Zum Beispiel, wenn Sie eine Liste der Aktienkurse vorstellen. - Die Daten würden regelmäßig geändert werden, werden und müssen synchron sein mit dem (in meinem Fall) Service, der die Daten ständig Berechnung / Abrufen
Vielen Dank im Voraus
Lösung
Wie kann ich meine Aktivität eingerichtet sein Hören auf den Service? Ist das der bester Weg, um dieses Problem zu nähern?
Sie haben drei wesentliche Optionen, wie ich es sehe:
-
Polling. Die
Activity
fragt in regelmäßigen Abständen dieService
die neuesten Daten. IMHO, ist diese Option saugt, aber es ist sicherlich möglich. -
Rückrufe. Per Antwort der JAX, registriert die
Activity
ein Callback-Objekt ( „Beobachter“) mit demService
. DieService
ruft eine Methode auf dem Rückruf, wenn die Datenänderungen, die wiederum die Benutzeroberfläche aktualisiert. Sie können ein Beispiel, der mit einemService
sehen hier . -
Broadcast-
Intents
. DieService
sendet eineIntent
übersendBroadcast()
auf einer Datenänderung. DieActivity
registrieren eineBroadcastReceiver
mitregisterReceiver()
, und dassBroadcastReceiver
wird eine eingehende Sendung informiert. Dies löst derActivity
die neuesten Daten aus derService
zu laden, oder möglicherweise nur die neuesten Daten in der SendungIntent
aus Extras zu bekommen. Sie können ein Beispiel für die Verwendung dieser Technik mit einemService
sehen hier .
Andere Tipps
Das klingt wie ein guter Kandidat für die Observer-Muster. Grundsätzlich werden Ihre Aktivität (The Observer) wird registriert sich mit dem Hintergrunddienst (die beobachtbaren) und Sie können Push oder Pull-Daten von Ihrer Aktivität. Ihr Beobachter in diesem Fall wird Ihre Aktivität und die beobachtbaren wird der Service.
Wenn Sie nichts über Design Patterns wissen kaufen „Head First Design Patterns“, es ist leicht zu lesen und ist voll von großen Informationen.
. PS: ich es lese jetzt
Ich bin wirklich, wirklich fragen, warum niemand einen einfachen Ansatz unter Verwendung eines EventBus durch was auch immer Bibliothek erwähnt. Das ist natürlich, wenn Sie mit RX nicht. Mein persönlicher Favorit ist EventBus von Greenrobot. https://github.com/greenrobot/EventBus
Mit nur ein paar Zeilen Code und keine Schnittstellen. Feuer ein Ereignis, und hören Sie es, wo immer Sie wollen. Es wird entkoppelt, es Thread-sicher ist, und es wird zum Absturz der App nicht.
Sie müssen bindService () verwenden, um die Aktivität mit laufenden Service zu binden und mit ihm kommunizieren.
public class BindingActivity extends Activity {
YourService mService;
boolean mBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to Your Service
Intent intent = new Intent(this, YourService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
public void onButtonClick(View v) {
if (mBound) {
// Call a method from your Service.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to the running Service, cast the IBinder and get instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
und Ihr Service wie:
public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
/**
* 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 LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
Sie einen Hintergrund-Thread ausgeführt haben, dass berechnet die Änderungen in der Liste. Dieser Thread braucht jetzt eine Möglichkeit, die GUI zu benachrichtigen, dass die Liste aktualisiert wurde.
Sie können eine Art von ArrayAdapter die Daten in die Listview zu erhalten. Die ArrayAdapter hat eine Methode namens Adpater. notifyDataSetChanged () jedes Mal, wenn Sie diese Methode aufrufen, der Adapter sehen, dass die entsprechenden Daten geändert hat und dann die Listenansicht mitteilen, dass sie bei der nächsten Möglichkeit aktualisieren sollte.