Die Kommunikation zwischen Android-Leistungen und Aktivitäten
Möchte ich die Entwicklung einer Android-App mit drei Aktionen und zwei Dienste.
Der erste Dienst, namens WebClientService, ruft eine REST-API alle 30 Sekunden, mit dem ein Handler, und hat er die aktive Tätigkeit mit dem Ergebnis.
Außerdem hat er einen zweiten Service namens DatabaseService, um zum aktualisieren einer lokalen DB.
Den Datenbank-Dienst aufgerufen wird, werden nur einmal onCreate der Tätigkeit (im Falle von app-Abstürzen und neu starten) und nur einmal am onRestart (in dieser Weise haben wir Daten, um zu zeigen, in Fall gab es Probleme mit der Konnektivität). Die Aktivitäten werden dann halten Sie sich aktualisiert, Dank der WebClientService benachrichtigt, dass die "lebendig" Aktivität alle 30 Sekunden.
Fragen sind:
-
Was ist der beste Weg, zu informieren, für ein update sowohl für die aktive Tätigkeit und den hintergrund DatabaseService?
Meine Idee ist die Verwendung sendBroadcast() innerhalb WebClientService und ein BroadcastReceiver in jeder Aktivität und in der DatabaseService, ist es der richtige Ansatz? -
Sollte ich verwenden den gleichen Ansatz für die Kommunikation zwischen AllMeetingRoomActivity und DatabaseService oder sollte ich eine Gebunden-Service?
Dank
UPDATE:
DatabaseService nicht ein hintergrund-Dienst mehr, sondern nur eine gemeinsame Instanz der db-Schicht zwischen WebClientService und die Aktivitäten.
Also Frage ist jetzt: ist es ein guter Ansatz, um gerade schreiben, dass meine 30 Sekunden-updates auf den lokalen db und ermöglichen, die Aktivitäten, aktualisieren sich alle paar Sekunden einfach das Lesen von der lokalen db?
Würde sich das auf die Leistung zu viel?
Kontext:
Folgt, was habe ich umgesetzt, bisher aber mit SettableFutures und damit muss erneut implementiert Dienste und-Sendungen habe ich einmal klar, wie man Sie effektiv zu kommunizieren:
public class MainActivity extends AppCompatActivity {
private TextView meetingsTextView;
private EditText mEdit, editSubject;
private final ConnectorInitializer clientInitializer = new ConnectorInitializer();
private AppConnector genericClient; //can use OutlookClient or a test client to talk with a mock server
@Override
protected void onCreate(Bundle savedInstanceState) {
//initializes client based on the settings in "config.json"
genericClient = clientInitializer.create(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
meetingsTextView = (TextView) findViewById(R.id.NowMeeting);
mEdit = (EditText)findViewById(R.id.editText);
editSubject = (EditText)findViewById(R.id.editSubject);
Futures.addCallback(genericClient.logon(this, scopes), new FutureCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
Log.d("APP", "-- Logged in. --");
databaseConnector.synchronouslyGetBackupFromLocalDatabase() //FUTURE
//callback here
//onSuccess, onFailure
}
@Override
public void onFailure(@NonNull Throwable t) {
Log.e("\n ~~~~>> logon \n", t.getMessage());
meetingsTextView.setText(R.string.Login_Failed);
}
});
}
/** At the moment the UI is not updated automatically every 30 seconds
* but manually using a refresh button
*/
public void getBookings(@SuppressWarnings("UnusedParameters") View view){
Log.d("APP", "Retrieve button clicked: "+(DateTime.now())+". Calling async getCalendar.");
meetingsTextView.setText(R.string.retrieving_events);
try{
Futures.addCallback( genericClient.getCalendarEvents(), new FutureCallback<String>(){
@Override
public void onSuccess(final String resultCalendars) {
Log.d("APP", "Success. Result: "+resultCalendars);
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("APP", "Calendars SUCCESSFULLY retrieved.");
String meetingsRetrieved = getString(R.string.calendar)+resultCalendars;
meetingsTextView.setText(meetingsRetrieved);
Toast.makeText(getApplicationContext(), "Success!", Toast.LENGTH_LONG).show();
}
});
databaseConnector.asyncUpdateLocalDbWithResults(); //FUTURE
//callback here
//onSuccess, onFailure
}
@Override
public void onFailure(@NonNull Throwable t) {
Log.e( "APP", "Calendar error. Cause: "+t.getLocalizedMessage() );
String retrieveError = "Retrieve error. \n\n\n"+t.getLocalizedMessage();
meetingsTextView.setText(retrieveError);
Toast.makeText(getApplicationContext(), "Fail!", Toast.LENGTH_LONG).show();
}
});
}catch(Exception ex){
Log.e("APP","Something went wrong in your code. Cause:"+ex);
}
}
- Können Sie erklären, mit einigen psedou code?
- Ich bin so verwirren, weil ich nicht weiß, was Sie wirklich wollen, zu tun
- Ich habe die Frage umformuliert und an einen skinny-Diagramm zur Veranschaulichung der gewünschten Architektur. Dank
- stackoverflow.com/a/27652660/4317945
- Aus der Beschreibung scheint es zu sein, dass Ihr DatabaseService sollte stattdessen ein ContentProvider - dann können Sie die ContentObservers und andere bestehende APIs, anstatt zu versuchen das Rad neu zu erfinden
- versuchen OttoBus Bibliothek, die ist leicht event-bus-system für android entwickelt von Squre.. square.github.io/otto
- Broadcast-Receiver oder ResultReceiver werden die besten Möglichkeiten, um dies zu erreichen
- Über ResultReceiver habe ich gelesen "die Verbindung wird unterbrochen, wenn Ihr Prozess geht Weg aus irgendeinem Grund". Tut BrodcastReceiver passen am besten dann? Mein service werden immer wieder auf Arbeitszeiten. Dank
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, dein Ansatz ist ok mit
BroadCastReceiver
. AllerdingsBroadCastReceiver
sollte verwendet werden, für die eine Globale Zweck (wie die Kommunikation zwischen 2 Anwendungen). Wenn Sie beabsichtigen, Sie zu verwendenBroadCastReceiver
für Ihre app nur, dass ich lieber mit LocalBroadcastManager statt. MitLocalBroadcastManager
schneller ist und mehr Sicherheit, wenn es gefangen werden können, nur durch Ihre app.Gibt es einen anderen Weg für die Kommunikation zwischen Ihrem
activity
s und Ihreservice
s ist mit EventBus. Es wird viel einfacher als mitBroadCastReceiver
(vor allem in der Weitergabe von Daten zwischen Ihnen).Update: Über Ihre update-Frage:
LocalBroadcastmanager
zu informieren, Ihre Aktivitäten zu aktualisieren.ExecutorService
für jedenexecute
(insert, update...). Eine weitere Sache zu prüfen, ist die Aktualisierung, die Häufig entladen wird Ihr Handy-Akku sehr, sehr schnell.LocalBroadCastReceiver
. Aber ich glaube nicht, dass Berufungrestful
service alle 30 s ist eine gute Idee. Es entlädt den Akku wirklich schnell, sogar schneller, als Sie denken. Als meine Meinung, 1 guter Ansatz für die Synchronisation der Daten zwischen mehreren Geräten ist: option 1. Die Verwendung von Sitzungen (für 1 Gerät online zu einem Zeitpunkt) option 2. Mit Google cloud messaging zu Benachrichtigen, das Gerät zu aktualisieren, wenn Sie es brauchen, anstatt die Aktualisierung alle 30s.Beste option je:
Verwenden
LocalBroadcastManager
. Mehr Referenz hier.MyService.java:
Fügen Sie unter Methode in service, Wann immer Sie wollen, aktualisieren von Daten vom Dienst für Aktivität, rufen Sie die Methode durch die übergabe
Arguments
.HomeActivity.java:
Hoffe, dies wird Ihnen helfen.
Können Sie binden die Dienstleistungen, die Tätigkeiten und die update-Benutzeroberfläche.
Oder Sie nutzen Bibliotheken wie Otto oder EventBus zum erstellen einer Verleger/Abonnent-Abhängigkeit und Benachrichtigen Sie Ihren Aktivitäten jedes mal wenn Sie Ihre Dienste ein update veröffentlichen von Informationen.
Verwenden event-bus für diese Mitteilung. EventBus ermöglicht publish-subscribe-Stil die Kommunikation zwischen den Komponenten, ohne dass die Komponenten explizit zu registrieren mit einem anderen (und damit über den jeweils anderen). Es ist ausschließlich als Ersatz für herkömmliche Java-in-process-event-Verteilung mit der expliziten Registrierung.
Gibt es eine Menge von Ihnen:
http://square.github.io/otto/
https://github.com/greenrobot/EventBus
Dies ist ein Beispiel von Otto Nutzung:
Post aus jedem thread (Haupt-oder hintergrund), im Fall eines Dienstes und empfangen von Ereignissen auf dem Haupt-thread: