Praktische Parallelität auf Android mit HaMeR

Im Abschnitt Parallelisierung unter Android mit HaMeR haben wir über die Grundlagen des HaMeR (Handler, Botschaft, und Lauffähig) Rahmen. Wir haben die Optionen sowie Wann und wie sie genutzt wurden, behandelt. 

Heute erstellen wir eine einfache Anwendung, um die erlernten Konzepte zu untersuchen. Mit einem praktischen Ansatz erfahren Sie, wie Sie die verschiedenen Möglichkeiten von HaMeR bei der Verwaltung der Parallelität auf Android anwenden können.

1. Die Beispielanwendung

Lass uns an die Arbeit gehen und ein paar posten Lauffähig und senden Botschaft Objekte in einer Beispielanwendung. Um es so einfach wie möglich zu gestalten, erkunden wir nur die interessantesten Teile. Alle Ressourcendateien und Standardaktivitätsaufrufe werden hier ignoriert. Daher empfehle ich Ihnen dringend, den Quellcode der Beispielanwendung mit ihren umfangreichen Kommentaren zu überprüfen. 

Die App besteht aus:

  • Zwei Aktivitäten, eine für Lauffähig ein anderes für Botschaft Anrufe
  • Zwei HandlerThread Objekte:
    • WorkerThread Anrufe von der Benutzeroberfläche empfangen und verarbeiten
    • CounterThread bekommen Botschaft Anrufe von der WorkerThread
  • Einige Dienstprogrammklassen (um Objekte bei Konfigurationsänderungen und für das Layout zu erhalten)

2. Runnables buchen und empfangen

Beginnen wir mit dem Experimentieren Handler.post (lauffähig) Methode und ihre Variationen, die ein lauffähiges zu einem hinzufügen MessageQueue einem Thread zugeordnet. Wir erstellen eine Aktivität namens RunableActivity, die mit einem Hintergrund-Thread kommuniziert WorkerThread.

Das RunableActivity instanziiert einen Hintergrund-Thread namens WorkerThread, vorbei ein Handler und ein WorkerThread.Callback als Parameter. Die Aktivität kann Anrufe tätigen WorkerThread Laden Sie asynchron eine Bitmap herunter und zeigen Sie zu einem bestimmten Zeitpunkt einen Toast an. Die Ergebnisse der vom Worker-Thread ausgeführten Aufgaben werden an übergeben RunableActivity von Runnables auf der Handler empfangen von WorkerThread.

2.1 Vorbereiten eines Handlers für RunnableActivity

Auf der RunableActivity wir schaffen ein Handler übergeben werden an WorkerThread. Das uiHandler wird mit der verbunden sein Looper vom UI-Thread, da es von diesem Thread aus aufgerufen wird.

public class RunnableActivity erweitert Activity // Handler, der die Kommunikation zwischen // dem WorkerThread und dem Activity protected Handler ermöglicht uiHandler; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // Vorbereiten des UI-Handlers zum Senden an WorkerThread uiHandler = new Handler (); 

2.2 Erklärung WorkerThread und seine Callback-Schnittstelle

Das WorkerThread ist ein Hintergrund-Thread, in dem wir verschiedene Aufgaben beginnen. Es kommuniziert mit der Benutzeroberfläche über die ResponseHandler und eine Rückmeldeschnittstelle, die während ihrer Instantiierung empfangen wird. Die Referenzen aus den Aktivitäten sind WeakReference <> Typ, da eine Aktivität zerstört werden kann und die Referenz verloren geht.

Die Klasse bietet eine Schnittstelle, die von der Benutzeroberfläche implementiert werden kann. Es erstreckt sich auch HandlerThread, eine Helferklasse, die auf gebaut wurde Faden das enthält schon ein Looper, und ein MessageQueue. Daher hat es das Richtige Konfigurationdas HaMeR-Framework verwenden.

Die öffentliche Klasse WorkerThread erweitert die Schnittstelle HandlerThread / ** *, um Aufrufe der Benutzeroberfläche zu ermöglichen. * / public interface Callback void loadImage (Bitmap-Bild); void showToast (String msg);  // Dieser Handler ist nur für die Veröffentlichung von Runnables in diesem Thread verantwortlich. Privater Handler postHandler; // Der Handler wird von MessageActivity und RunnableActivity // empfangen, die für den Empfang von Runnable-Aufrufen verantwortlich sind, die // auf der Benutzeroberfläche verarbeitet werden. Der Rückruf wird diesen Prozess unterstützen. private WeakReference ResponseHandler; // Rückruf von der Benutzeroberfläche // Es handelt sich um eine WeakReference, da diese // während "Konfigurationsänderungen" und anderen privaten WeakReference-Ereignissen ungültig gemacht werden kann Ruf zurück; private final String imageAUrl = "https://pixabay.com/static/uploads/photo/2016/08/05/18/28/mobile-phone-1572901_960_720.jpg"; / ** * Der Konstruktor erhält einen Handler und einen Rückruf von der UI * @param responseHandler, der für die Veröffentlichung des Runnable auf die UI * @param verantwortlich ist. Callback funktioniert zusammen mit dem responseHandler *, wodurch Aufrufe direkt auf der UI * / public WorkerThread (Handler) möglich sind ResponseHandler, Callback Callback) Super (TAG); this.responseHandler = neue WeakReference <> (responseHandler); this.callback = new WeakReference <> (Rückruf); 

2.3 Initialisierung WorkerThread

Wir müssen eine Methode hinzufügen WorkerThread von den Aktivitäten aufgerufen werden, die den Thread vorbereiten postHandler für den Einsatz. Die Methode muss erst nach dem Start des Threads aufgerufen werden.

public class WorkerThread erweitert HandlerThread / ** * Bereiten Sie den postHandler vor. * Es muss aufgerufen werden, nachdem der Thread gestartet wurde. * / Public void preparHandler () postHandler = new Handler (getLooper ()); 

Auf der RunableActivity wir müssen umsetzen WorkerThread.Callback und initialisieren Sie den Thread, damit er verwendet werden kann.

public class RunnableActivity erweitert Activity implementiert WorkerThread.Callback // BackgroundThread, das für das Herunterladen des Images verantwortlich ist. protected WorkerThread workerThread; / ** * Initialisiert die @link WorkerThread -Instanz * nur, wenn sie noch nicht initialisiert wurde. * / public void initWorkerThread () if (workerThread == null) workerThread = new WorkerThread (uiHandler, this); workerThread.start (); workerThread.prepareHandler ();  / ** * setze das im bg-Thread heruntergeladene Bild auf imageView * / @Override public void loadImage (Bitmap-Bild) myImage.setImageBitmap (Bild);  @Override public void showToast (letzte Zeichenfolge) // muss implementiert werden

2.4 Verwenden von Handlerpost () im WorkerThread

Das WorkerThread.downloadWithRunnable () Diese Methode lädt eine Bitmap herunter und sendet sie an RunableActivity in einer Bildansicht angezeigt werden. Es zeigt zwei grundlegende Anwendungen des Handler.post (Runable Run) Befehl:

  • So lassen Sie zu, dass ein Thread ein ausführbares Objekt in einer MessageQueue bereitstellt, die mit ihm verbunden ist .Post() wird für einen Handler aufgerufen, der dem Looper des Threads zugeordnet ist.
  • Um die Kommunikation mit anderen Threads zu ermöglichen, wann .Post() wird für einen Handler aufgerufen, der mit dem Looper eines anderen Threads verknüpft ist.
  1. Das WorkerThread.downloadWithRunnable () Methode Beiträge a Lauffähig zum WorkerThread's MessageQueue Verwendung der postHandler, ein Handler verknüpft mit WorkThread's Looper.
  2. Wenn das Runable verarbeitet wird, lädt es a Bitmap auf der WorkerThread.
  3. Nachdem die Bitmap heruntergeladen wurde, wird die ResponseHandler, Ein Handler, der dem UI-Thread zugeordnet ist, wird verwendet, um ein lauffähiges Programm auf dem zu veröffentlichen RunableActivity die die Bitmap enthält.
  4. Das Runable wird verarbeitet und das WorkerThread.Callback.loadImage wird verwendet, um das heruntergeladene Bild auf einem auszustellen Bildansicht.
Die öffentliche Klasse WorkerThread erweitert HandlerThread / ** * post ein Runable zum WorkerThread. * Laden Sie eine Bitmap herunter und sendet das Bild * an die Benutzeroberfläche @link RunnableActivity *. Verwenden Sie dazu die @link #responseHandler -Hilfe von @link #callback * / public void downloadWithRunnable () // post Runnable to WorkerThread postHandler.post (neues Runnable () @Override public void run () try // schläft 2 Sekunden lang, um die Langzeitoperation TimeUnit.SECONDS zu emulieren .sleep (2); // Bild herunterladen und an UI senden downloadImage (imageAUrl); catch (InterruptedException e) e.printStackTrace (););  / ** * Laden Sie eine Bitmap mit ihrer URL herunter und * senden Sie das heruntergeladene Bild an die Benutzeroberfläche. * / Private void downloadImage (String urlStr) // Eine Verbindung erstellen HttpURLConnection connection = null; try URL url = neue URL (urlStr); Verbindung = (HttpURLConnection) url.openConnection (); // Den Stream von der URL abrufen InputStream in = new BufferedInputStream (connection.getInputStream ()); letzte Bitmap Bitmap = BitmapFactory.decodeStream (in); if (Bitmap! = null) // Sendet die heruntergeladene Bitmap und eine Rückmeldung an die Benutzeroberfläche loadImageOnUI (Bitmap);  else  catch (IOException e) e.printStackTrace ();  Schließlich if (Verbindung! = null) connection.disconnect ();  / ** * sendet ein Bitmap an das ui *, das ein Runable an den @link #responseHandler * sendet, und verwendet den @link Callback * / private void loadImageOnUI (endgültiges Bitmap-Bild) Log.d (TAG, "loadImageOnUI (" + image + ")"); if (checkResponse ()) responseHandler.get (). post (new Runnable ()) @Orride public void run () callback.get (). loadImage (image);;  // Vergewissern Sie sich, dass responseHandler verfügbar ist //, wenn die Aktivität nicht an einem Zerstörungsereignis vorbeigeht. private boolean checkResponse () return responseHandler.get ()! = null; 

2.5 Verwenden von Handler.postAtTime () und Activity.runOnUiThread ()

Das WorkerThread.toastAtTime ()plant, dass eine Aufgabe zu einem bestimmten Zeitpunkt ausgeführt wird, und zeigt a Toast an den Benutzer. Die Methode veranschaulicht die Verwendung von Handler.postAtTime () und das Activity.runOnUiThread ().

  • Handler.postAtTime (Lauffähiger Lauf, lange BetriebszeitenMillis) Posten ein lauffähiges zu einer bestimmten Zeit.
  • Activity.runOnUiThread (Runable Run) verwendet den standardmäßigen UI-Handler, um eine ausführbare Datei im Haupt-Thread zu veröffentlichen.
Die öffentliche Klasse WorkerThread erweitert HandlerThread / ** *, um einen Toast auf der Benutzeroberfläche anzuzeigen. * plant die Aufgabe unter Berücksichtigung der aktuellen Uhrzeit. * Es kann jederzeit geplant werden, wir verwenden * 5 Sekunden, um das Debuggen zu erleichtern. * / Public void toastAtTime () Log.d (TAG, "toastAtTime (): current -" + Calendar.getInstance (). ToString ()); // Sekunden um die aktuelle Zeit hinzuzufügen int delaySeconds = 5; // Testen mit einem echten Datum Calendar scheduleDate = Calendar.getInstance (); // Festlegen eines zukünftigen Datums unter Berücksichtigung der Verzögerung in Sekunden definieren // Wir verwenden diesen Ansatz, um das Testen zu erleichtern. // Es könnte ein benutzerdefiniertes Datum verwendet werden, auch "scheduleDate.set" (scheduleDate.get (Calendar.YEAR)) "scheduleDate.get (Calendar.MONTH)", "scheduleDate.get" (Calendar.DAY_OF_MONTH), "scheduleDate.get" (Calendar.HOUR_OF_DAY) ), scheduleDate.get (Calendar.MINUTE), scheduleDate.get (Calendar.SECOND) + delaySeconds); Log.d (TAG, "toastAtTime (): Scheduling at -" + scheduleDate.toString ()); long schedule = berechneUptimeMillis (scheduleDate); // Zu einem bestimmten Zeitpunkt lauffähig postHandler.postAtTime (new Runnable () @Override public void run () if (callback! = null) callback.get (). showToast ("Toast wurde mit 'postAtTime ()' aufgerufen). ");, geplant);  / ** * Berechnet die @link SystemClock # uptimeMillis () bis * zu einem bestimmten Kalenderdatum. * / private long berechneUptimeMillis (Kalenderkalender) long time = calendar.getTimeInMillis (); long currentTime = Calendar.getInstance (). getTimeInMillis (); Long Diff = Zeit - aktuelle Zeit; return SystemClock.uptimeMillis () + diff; 
public class RunnableActivity erweitert Activity implementiert WorkerThread.Callback / ** * Callback von @link WorkerThread * Verwendet @link #runOnUiThread (Runnable), um * solche Methode * / @Override zu zeigen. public void showToast (final String msg)  Log.d (TAG, "showToast (" + msg + ")"); runOnUiThread (new Runnable () @Override public void run () Toast.makeText (getApplicationContext (), msg, Toast.LENGTH_LONG) .show ();; 

3. Nachrichten senden mit MessageActivity & WorkerThread

Lassen Sie uns als Nächstes einige verschiedene Verwendungsmöglichkeiten erkunden MessageActivity  senden und verarbeiten Botschaft Objekte. Das MessageActivity instantiiert WorkerThread, vorbei ein Handler als Parameter. Das WorkerThread hat einige öffentliche Methoden mit Aufgaben, die von der Aktivität aufgerufen werden müssen, um eine Bitmap herunterzuladen, eine zufällige Bitmap herunterzuladen oder eine auszustellen Toast nach einiger verspäteter zeit. Die Ergebnisse all dieser Vorgänge werden an gesendet MessageActivity mit Botschaft Objekte gesendet von der ResponseHandler.

3.1 Vorbereiten des Response Handlers von MessageActivity

Wie in der RunableActivity, in dem MessageActivity wir müssen ein instanziieren und initialisieren WorkerThread Senden einer Handler um Daten vom Hintergrund-Thread zu erhalten. Dieses Mal werden wir dies jedoch nicht implementieren WorkerThread.Callback; Stattdessen erhalten wir Antworten von der WorkerThread ausschließlich von Botschaft Objekte.

Da die meisten MessageActivity und RunableActivity Code ist im Grunde der gleiche, wir konzentrieren uns nur auf die uiHandler Vorbereitung, die an gesendet wird WorkerThread um Nachrichten davon zu erhalten.

Lassen Sie uns zunächst einige zur Verfügung stellen int Schlüssel, die als Bezeichner für die Message-Objekte verwendet werden.

public class MessageActivity erweitert Activity // In Message.what () -Feld verwendete Nachrichtenkennung public static final int KEY_MSG_IMAGE = 2; public static final int KEY_MSG_PROGRESS = 3; public static final int KEY_MSG_TOAST = 4; 

Auf MessageHandler Implementierung müssen wir verlängern Handler und implementieren die handleMessage (Nachricht) Methode, bei der alle Nachrichten verarbeitet werden. Beachten Sie, dass wir abholen Nachricht.was Um die Nachricht zu identifizieren, erhalten wir auch verschiedene Arten von Daten Message.obj. Lasst uns das Wichtigste schnell durchgehen Botschaft Eigenschaften vor dem Eintauchen in den Code.

  • Nachricht.wasint Identifizierung der Botschaft
  • Nachricht.arg1int beliebiges Argument
  • Nachricht.arg2int beliebiges Argument
  • Message.objObjekt verschiedene Arten von Daten zu speichern
Die öffentliche Klasse MessageActivity erweitert den Activity / ** * - Handler, der für die Verwaltung der Kommunikation * vom @link WorkerThread aus verantwortlich ist. Es sendet Messages * zurück an @link MessageActivity und behandelt * diese Messages * / public-Klasse MessageHandler erweitert den Handler @Override public void handleMessage (Message msg)  Bitmap bmp = (Bitmap) msg.obj; myImage.setImageBitmap (bmp); brechen;  // behandelt progressBar-Aufrufe case KEY_MSG_PROGRESS: if ((boolean) msg.obj) progressBar.setVisibility (View.VISIBLE); else progressBar.setVisibility (View.GONE); brechen;  // Handle Toast, der mit einem Nachrichtenverzögerungsfall gesendet wird KEY_MSG_TOAST: String msgText = (String) msg.obj; Toast.makeText (getApplicationContext (), msgText, Toast.LENGTH_LONG) .show (); brechen;  // Handler, der die Kommunikation zwischen // dem WorkerThread und dem Activity protected MessageHandler ermöglicht uiHandler;  

3.2 Senden von Nachrichten mit WorkerThread

Kommen wir jetzt zum WorkerThread Klasse. Wir werden Code hinzufügen, um eine bestimmte Bitmap herunterzuladen, und Code, um eine zufällige herunterzuladen. Um diese Aufgaben zu erledigen, senden wir Botschaft Objekte aus dem WorkerThread zu sich selbst und senden die Ergebnisse zurück an MessageActivity unter Verwendung exakt derselben Logik, die zuvor für die angewendet wurde RunableActivity.

Zuerst müssen wir das erweitern Handler um die heruntergeladenen Nachrichten zu verarbeiten.

public class WorkerThread erweitert HandlerThread // send und verarbeitet download Nachrichten auf dem privaten WorkerThread-HandlerMsgImgDownloader handlerMsgImgDownloader; / ** * Schlüssel zum Identifizieren der Schlüssel von @link Message # what * von vom @link #handlerMsgImgDownloader gesendeten Nachrichten * / private final int MSG_DOWNLOAD_IMG = 0; // msg, die ein einzelnes img private final int herunterladen MSG_DOWNLOAD_RANDOM_IMG = 1; // msg, der zufällige Download img / ** * Handler, der für das Verwalten des Bilddownloads verantwortlich ist. * Er sendet und verarbeitet Nachrichten, die dann * die @link Message # what * @link #MSG_DOWNLOAD_IMG identifizieren: Einzelbild * @link #MSG_DOWNLOAD_RANDOM_IMG: random image * / private class HandlerMsgImgDownloader erweitert Handler private HandlerMsgImgDownloader (Looper looper) super (looper);  @Override public void handleMessage (Message msg) showProgressMSG (true); switch (msg.what) case MSG_DOWNLOAD_IMG: // empfängt eine einzelne URL und lädt sie herunter. String url = (String) msg.obj; downloadImageMSG (url); brechen;  case MSG_DOWNLOAD_RANDOM_IMG: // empfängt einen String [] mit mehreren URLs // lädt ein Bild zufällig herunter String [] urls = (String []) msg.obj; Random random = new Random (); String-URL = URLs [random.nextInt (urls.length)]; downloadImageMSG (url);  showProgressMSG (false); 

Das downloadImageMSG (String-URL) Methode ist im Grunde die gleiche wie die downloadImage (String-URL) Methode. Der einzige Unterschied besteht darin, dass der erste die heruntergeladene Bitmap durch Senden einer Nachricht mit dem Befehl zurück an die Benutzeroberfläche sendet ResponseHandler.

public class WorkerThread erweitert HandlerThread / ** * Laden Sie eine Bitmap mithilfe ihrer URL herunter und zeigen Sie sie der Benutzeroberfläche an. * Der einzige Unterschied zu @link #downloadImage (String) * besteht darin, dass das Bild mit einer Nachricht an die Benutzeroberfläche zurückgeschickt wird * / private void downloadImageMSG (String urlStr) // Eine Verbindung erstellen HttpURLConnection connection = null; try URL url = neue URL (urlStr); Verbindung = (HttpURLConnection) url.openConnection (); // Den Stream von der URL abrufen InputStream in = new BufferedInputStream (connection.getInputStream ()); letzte Bitmap Bitmap = BitmapFactory.decodeStream (in); if (Bitmap! = null) // Sende die heruntergeladene Bitmap und ein Feedback an die Benutzeroberfläche loadImageOnUIMSG (Bitmap);  catch (IOException e) e.printStackTrace ();  Schließlich if (Verbindung! = null) connection.disconnect (); 

Das loadImageOnUIMSG (Bitmap-Bild) ist verantwortlich für das Senden einer Nachricht mit der heruntergeladenen Bitmap an MessageActivity

 / ** * sendet eine Bitmap an das ui * Senden einer Nachricht an den @link #responseHandler * / private void loadImageOnUIMSG (endgültiges Bitmap-Bild) if (checkResponse ()) sendMsgToUI (responseHandler.get (). reachMessage ( MessageActivity.KEY_MSG_IMAGE, image));  / ** * Fortschrittsleiste auf der Benutzeroberfläche anzeigen / ausblenden. * Es verwendet den @link #responseHandler, um * eine Nachricht über die Benutzeroberfläche zu senden * / private void showProgressMSG (boolean show) Log.d (TAG, "showProgressMSG ()"); if (checkResponse ()) sendMsgToUI (responseHandler.get (). reachMessage (MessageActivity.KEY_MSG_PROGRESS, show)); 

Beachten Sie das, anstatt ein zu erstellen Botschaft Objekt von Grund auf neu, wir verwenden die Handler.obtainMessage (int what, Object obj) Methode zum Abrufen von a Botschaft aus dem globalen Pool, um einige Ressourcen zu sparen. Es ist auch wichtig zu wissen, dass wir das anrufen erhaltenMessage () auf der ResponseHandler, erhalten ein Botschaft verknüpft mit MessageActivity's Looper. Es gibt zwei Möglichkeiten, a abzurufen Botschaft aus dem globalen Pool: Message.obtain () und Handler.obtainMessage ().

Das einzige, was bei der Image-Download-Aufgabe übrig bleibt, ist, die Methoden zum Senden einer Botschaft zu WorkerThread um den Download zu starten. Beachten Sie, dass wir diesmal anrufen werden Message.obtain (Handler-Handler, int was, Objekt obj) auf handlerMsgImgDownloader, Verknüpfen der Nachricht mit WorkerThread's Schläger.

 / ** * sendet eine Nachricht an den aktuellen Thread * mit dem @link #handlerMsgImgDownloader *, um ein einzelnes Bild herunterzuladen. * / public void downloadWithMessage () Log.d (TAG, "downloadWithMessage ()"); showOperationOnUIMSG ("Sending Message…"); if (handlerMsgImgDownloader == null) handlerMsgImgDownloader = new HandlerMsgImgDownloader (getLooper ()); Message message = Message.obtain (handlerMsgImgDownloader, MSG_DOWNLOAD_IMG, imageBUrl); handlerMsgImgDownloader.sendMessage (Nachricht);  / ** * sendet eine Nachricht an den aktuellen Thread * mit dem @link #handlerMsgImgDownloader *, um ein zufälliges Bild herunterzuladen. * / public void downloadRandomWithMessage () Log.d (TAG, "downloadRandomWithMessage ()"); showOperationOnUIMSG ("Sending Message…"); if (handlerMsgImgDownloader == null) handlerMsgImgDownloader = new HandlerMsgImgDownloader (getLooper ()); Message message = Message.obtain (handlerMsgImgDownloader, MSG_DOWNLOAD_RANDOM_IMG, imagesUrls); handlerMsgImgDownloader.sendMessage (Nachricht); 

Eine weitere interessante Möglichkeit ist das Senden Botschaft Objekte, die zu einem späteren Zeitpunkt mit dem Befehl bearbeitet werden sollen Message.sendMessageDelayed (Nachricht msg, long timeMillis).

/ ** * Toast nach einer verspäteten Zeit anzeigen. * * Eine Nachricht mit verzögerter Zeit auf dem WorkerThread senden * und eine neue Nachricht an @link MessageActivity * mit einem Text senden, nachdem die Nachricht verarbeitet wurde. * / public void startMessageDelay () // message delay long delay = 5000; String msgText = "Hallo von WorkerThread!"; // Handler, der für das Senden der Nachricht an WorkerThread verantwortlich ist // Verwendung von Handler.Callback (), um zu vermeiden, dass die Handler-Klasse Handler Handler = new Handler erweitert werden muss (neuer Handler.Callback () @Override public HandleMessage (Message msg) responseHandler) .get (). sendMessage (responseHandler.get (). reachMessage (MessageActivity.KEY_MSG_TOAST, msg.obj)); return true;); // Senden einer Nachricht handler.sendMessageDelayed (handler.obtainMessage (0, msgText), delay); 

Wir haben ein erstellt Handler ausdrücklich zum Versenden der verspäteten Nachricht. Anstatt das zu erweitern Handler Klasse, nahmen wir den Weg der Instantiierung eines Handler mit der Handler.Rückruf Schnittstelle, für die wir die implementiert haben handleMessage (Message msg) Methode, um das verzögerte zu verarbeiten Botschaft.

4. Fazit

Sie haben bereits genug Code gesehen, um zu verstehen, wie Sie die grundlegenden Konzepte des HaMeR-Frameworks zur Verwaltung der Parallelität auf Android anwenden können. Es gibt einige andere interessante Features des endgültigen Projekts, die auf GitHub gespeichert sind, und ich empfehle Ihnen dringend, es auszuprobieren. 

Zum Schluss habe ich noch ein paar letzte Überlegungen, die Sie beachten sollten:

  • Vergessen Sie nicht, den Aktivitätslebenszyklus von Android zu berücksichtigen bei der Arbeit mit HaMeR und Threads im Allgemeinen. Andernfalls schlägt Ihre App möglicherweise fehl, wenn der Thread versucht, auf Aktivitäten zuzugreifen, die aufgrund von Konfigurationsänderungen oder aus anderen Gründen zerstört wurden. Eine gängige Lösung ist die Verwendung von a RetainedFragment um den Thread zu speichern und den Hintergrund-Thread bei jeder Zerstörung der Aktivität mit der Referenz der Aktivität zu füllen. Sehen Sie sich die Lösung im abschließenden Projekt auf GitHub an.
  • Aufgaben, die aufgrund von ausgeführt werden Lauffähig und Botschaft bearbeitete Objekte Handler nicht asynchron laufen. Sie werden synchron in dem Thread ausgeführt, der dem Handler zugeordnet ist. Um es asynchron zu machen, müssen Sie einen anderen Thread erstellen, senden und senden Botschaft/Lauffähig Objekt darauf und erhalten die Ergebnisse zum richtigen Zeitpunkt.

Wie Sie sehen, bietet das HaMeR-Framework viele verschiedene Möglichkeiten. Es ist eine recht offene Lösung mit vielen Optionen für die Verwaltung der Parallelität auf Android. Diese Eigenschaften können gegenüber den Vorteilen sein AsyncTask, abhängig von Ihren Bedürfnissen. Entdecken Sie mehr über das Framework und lesen Sie die Dokumentation. Damit schaffen Sie großartige Dinge.

Bis bald!