Erstellen von Android-Diensten

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Erstellen einer Android-App

Ein Android-Dienst ist eine Anwendung ohne Benutzeroberfläche, die Hintergrundaufgaben ausführt. Im Wesentlichen gibt es zwei Arten von Diensten:

  • Ein gestarteter Dienst: Dieser Dienst wird von einer Android-Anwendung gestartet. Der Dienst kann unendlich im Hintergrund ausgeführt werden, auch wenn die Anwendung geschlossen ist. Diese Art Dienst führt in der Regel eine einzelne Aufgabe aus und wird automatisch nach Beendigung der Aufgabe angehalten.
  • Ein gebundener Dienst: Dieser Dienst wird nur ausgeführt, wenn er an eine Android-Anwendung gebunden ist. Es gibt eine Interaktion zwischen der Anwendung und dem Dienst, und der Dienst bleibt so lange aktiv, bis die Anwendung die Bindung aufhebt. Mehrere Anwendungen können an denselben Dienst gebunden sein.

Zum Erstellen eines Android-Dienst-Projekts:

  1. Verwenden Sie den Neuen Android-Dienst-Experten, um den Android-Dienst zu erstellen. Siehe Erstellen eines Android-Dienstes.
  2. Verwenden Sie den Hinzufügen eines neuen Android-Dienstes-Experten, um den Android-Dienst der Geräteübergreifende Anwendung hinzuzufügen. Siehe Hinzufügen eines Android-Dienstes zu einer Anwendung.

Es gibt einige Unterschiede zwischen einer Einzelanwendung und einer Android-Dienst-Projektanwendung:

Erstellen eines Android-Dienstes

RAD Studio stellt einen Experten bereit, um Android-Dienst-Projekte zu erstellen.

Um ein neues Android-Dienst-Projekt zu erstellen, wählen Sie Datei > Neu > Weitere und navigieren dann zu:

  • Delphi-Projekte > Android-Dienst

Verwenden Sie diesen Experten, um den Typ des Dienstes, lokal oder remote, festzulegen.

  • Ein lokaler Dienst ist für eine Anwendung privat. Der Zugriff von anderen Anwendungen wird durch Hinzufügen einer Zeile zur Android-Manifestdatei blockiert:
<service android:exported="false" android:name="com.embarcadero.services.<service_name>"/>
  • Ein Remote-Dienst ist öffentlich, und andere Anwendungen können darauf zugreifen. Der Zugriff auf den Dienst wird durch das Hinzufügen einer Zeile zur Android-Manifestdatei erteilt:
<service android:exported="true" android:name="com.embarcadero.services.<service_name>"/>

Weitere Informationen über die verschiedenen Optionen finden Sie unter Android-Dienst.

Weitere Informationen über die Android-Manifestattribute finden Sie unter Exported Provider Element (EN).

Hinweis: Falls der Entwickler die Datei <SERVICE-NAME>.template.java (lokale Vorlagendatei) und den Ordner JavaClasses im Stammordner eines von einem früheren Produkt-Release generierten Android-Dienstordners geändert hat, ist es sehr wichtig, die gleichen Änderungen in die von RAD Studio 10.4. generierte lokale Vorlagendatei zu übernehmen.

Hinzufügen eines Android-Dienstes zu einer Anwendung

Android-Dienste sind keine Einzelanwendungen, sie arbeiten zusammen mit Geräteübergreifende Anwendungen.

Wenn der Dienst erstellt ist, wird er im Projekte-Fenster als lib<Projektname>.so angezeigt.

Zum Hinzufügen des Android-Dienst-Projekts zu der Geräteübergreifende Anwendung:

  1. Fügen Sie dem Datenmodul alle visuellen Komponenten und dem Code die Funktionen und Prozeduren hinzu.
  2. Speichern Sie das Android-Dienstprojekt.
    Hinweis 1: Speichern Sie jedes Android-Dienstprojekt in einem eigenen Ordner.
    Hinweis 2: Nennen Sie das Android-Dienstprojekt nicht Service.
  3. Erzeugen Sie das Android-Dienstprojekt, bevor Sie es der Anwendung hinzufügen, um die Binärdateien zu generieren.
  4. Fügen Sie dem Projekte-Fenster die Anwendung hinzu, zu der Sie den Dienst hinzufügen möchten:
    1. Klicken Sie bei einer vorhandenen Anwendung mit der rechten Maustaste auf die Projektgruppe, und wählen Sie Existierendes Projekt hinzufügen.
    2. Klicken Sie bei einer neuen geräteübergreifenden Anwendung mit der rechten Maustaste auf die Projektgruppe, wählen Sie Neues Projekt hinzufügen, und navigieren Sie dann zu:
      • Delphi-Projekte > Geräteübergreifende Anwendung.
  5. Wählen Sie für die geräteübergreifende Anwendung die Android-Zielplattform aus.
    1. Klicken Sie mit der rechten Maustaste auf die Android-Zielplattform, und wählen Sie Android-Dienst hinzufügen.
    2. Der Experte Neuen Android-Dienst hinzufügen wird geöffnet. Es gibt zwei Optionen, um einen neuen Android-Dienst hinzuzufügen. Wählen Sie eine der beiden Optionen aus:
      1. Dateien automatisch im Projektbasispfad suchen.
        • Wählen Sie diese Option, um den Ordner auszuwählen, in dem das Android-Dienstprojekt gespeichert ist. Der Experte sucht die erforderliche Dateien automatisch.
          Warnung: Wenn sich in dem angegebenen Ordner mehr als ein Android-Dienst befindet, wählt der Experte einen davon zufällig aus. Wählen Sie die zweite Option, wenn Sie einen bestimmten Android-Dienst hinzufügen möchten.
        • Klicken Sie auf Weiter.
        • Klicken Sie auf ProjectOptionsEllipsis.jpg, um den Ordner auszuwählen, in dem das Android-Dienstprojekt gespeichert ist.
      2. Ich wähle alle erforderlichen Dateien manuell aus.
        • Klicken Sie auf diese Option, wenn Sie alle erforderlichen Dateien manuell auswählen möchten.
          Warnung: Vergewissern Sie sich, dass Sie Schritt 3 ausgeführt haben. Andernfalls stehen die Binärdateien nicht zur Verfügung.
        • Klicken Sie auf Weiter.
        • Klicken Sie auf ProjectOptionsEllipsis.jpg, um die erforderlichen Dateien auszuwählen.
    3. Klicken Sie auf Weiter.
      1. Wenn alles korrekt ist, werden die Dateien, die Ihrer geräteübergreifenden Anwendung hinzugefügt werden sollen, aufgeführt.
      2. Wenn ein zusätzliches Fenster mit der Aufforderung, Information über die Android-Dienstpfade anzugeben, angezeigt wird, speichern und erzeugen Sie den Android-Dienst, und versuchen Sie es anschließend erneut.
  6. Klicken Sie auf Fertig stellen, um der Anwendung die Dateien hinzuzufügen:
    • Die Hauptbinärdatei lib<Projektname>.so. Die Binärdatei wird dem Bereitstellungs-Manager hinzugefügt.
    • Die Datei libProxyAndroidService.so. Diese Bibliothek wird dem Bereitstellungs-Manager hinzugefügt.
      Hinweis: Diese Datei wird von allen der Anwendung hinzugefügten Diensten gemeinsam genutzt.
    • Die Java-Archivdatei <Projektname>.jar. Die JAR-Datei wird im Projekte-Fenster dem Knoten Bibliotheken unter der Android-Zielplattform hinzugefügt.
    • Die Datenmoduldatei <Projektname>.pas. Das Datenmodul wird dem Projekte-Fenster hinzugefügt.
  7. Compilieren Sie die geräteübergreifende Anwendung, um die Android-Manifestdatei zu generieren. Die dem zuvor ausgewählten Diensttyp (lokal oder remote) entsprechende Zeile wird automatisch hinzugefügt. Siehe Erstellen eines Android-Dienstes.
    Hinweis: Jeder Dienst benötigt eine entsprechende <service>-Deklaration in der Datei AndroidManifest.xml. Diese wird von der IDE automatisch hinzugefügt.

Hinzufügen mehrerer Android-Dienste zu einer Anwendung

Sie können einer Android-Anwendung eine beliebige Anzahl von Diensten hinzufügen.

Befolgen Sie die Schritte unter Hinzufügen eines Android-Dienstes zu einer Anwendung für jeden hinzuzufügenden Dienst.

Berücksichtigen Sie Folgendes:

  • Wenn sich im gleichen Ordner mehrere Android-Dienstprojekte befinden, wählen Sie die zweite Option in Schritt 5.2. Andernfalls fügt der Experte möglicherweise einen unerwünschten Android-Dienst hinzu.
  • Vergeben Sie für jedes Projekt einen anderen Namen, bevor Sie es der Hauptanwendung hinzufügen:
    • Das Android-Dienstprojekt lib<Dienstname>.so.
    Hinweis: Nennen Sie das Android-Dienstprojekt nicht Service.
    • Die Unit-Datei.
    • Das Datenmodul, indem Sie im Objektinspektor die Eigenschaft Name ändern.

Projektabhängigkeiten

Android-Dienst-Projekte, die den Geräteübergreifenden Anwendungen hinzugefügt wurden, erscheinen als Projektabhängigkeiten.

Die Android-Dienst-Projekte, die an eine Host-Anwendung gebunden sind, werden automatisch in Projektabhängigkeiten aktiviert, damit sie immer vor der Host-Anwendung erzeugt werden.

Löschen eines Android-Dienstes aus einer Anwendung

Wählen Sie in der Geräteübergreifenden Anwendung die Android-Zielplattform aus.

  1. Klicken Sie in der Android-Zielplattform mit der rechten Maustaste und wählen Sie Android-Dienst entfernen.
  2. Der Android-Dienst entfernen-Experte wird angezeigt.
  3. Wählen Sie die von der Liste zu entfernenden Dienste aus.
  4. Klicken Sie auf Weiter.
  5. Der Experte zeigt eine Liste von auszuführenden Aktionen, wie entfernen der Datenmodule, .so-Erweiterungsdateien und .jar-Erweiterungsdateien.
  6. Klicken Sie auf Beenden.

Starten eines Dienstes

Dienste können mit ALocalServiceConnection.StartService('<Dienstname>') und ALocalServiceConnection.BindService('<Dienstname;') oder ARemoteServiceConnection.StartService('<Dienstname>') und ARemoteServiceConnection.BindService('<Dienstname>') gestartet werden.

Sie initialisieren die Variable TLocalServiceConnection mit einem bestimmten Dienst, wenn Sie den Dienst starten oder ihn einbinden; danach müssen Sie für die restlichen Methoden nicht auf den Dienstnamen verweisen.

Nach dem Hinzufügen eines Android-Dienstes zu einer geräteübergreifenden Anwendung:

  1. Beziehen Sie die folgende Unit in die uses-Klausel des Interface ein:
    Uses
      System.Android.Service; // Unit that contains the methods to work with services.
    
  2. Beziehen Sie die Unit <Dienstname.pas> in die uses-Klausel der Implementierung ein. Auf diese Weise können Sie alle im Dienst-Datenmodul definierten Methoden verwenden.
    implementation
    
    uses
      MyLocalService; //Key sensitive
    
    {$R *.fmx}
    
  3. Erstellen Sie eine TLocalServiceConnetion-Variable für einen lokalen Dienst oder eine TRemoteServiceConnection-Variable für einen Remote-Dienst.
    1. Deklarieren Sie die TLocalServiceConnection/TRemoteServiceConnection-Variable:
      type
        TForm1 = class(TForm)
          ...
        private
          { Private declarations }
          FServiceConnection1: TLocalServiceConnection; // For a local service.
          FServiceConnection2: TRemoteServiceConnection; // For a remote service.
        public
          { Public declarations }
        end;
      
    2. Erstellen Sie die TLocalServiceConnection/TRemoteServiceConnection-Variable:
      FServiceConnection1 := TLocalServiceConnection.Create; // For a local service.
      FServiceConnection2 := TRemoteServiceConnection.Create; // For a remote service.
      

Gestarteter Dienst

Rufen Sie für einen gestarteten Dienst StartService('<Dienstname>') auf, um den Dienst zu starten.

Beim Verwenden von Diensten als gestartet müssen Sie den Dienstprozess, der den Dienst anhält, mit JavaService.stopSelf; verwalten.

"Sticky" Start

Das Ereignis OnStartCommand für den Dienst ist standardmäßig als START_NOT_STICKY definiert.

  • START_STICKY (EN) wird für Dienste verwendet, die bei Bedarf explizit gestartet und angehalten werden. Das System versucht, einen abgebrochenen Dienst neu zu erstellen.
  • START_NOT_STICKY (EN) wird für Dienste verwendet, die nur weiterhin ausgeführt werden sollen, solange an sie gesendete Befehle verarbeitet werden. Wenn der Prozess abgebrochen wurde, wird der Dienst nicht automatisch neu gestartet.

Wenn Sie START_STICKY für das Ereignis OnStartCommand anwenden möchten, müssen Sie das für den Dienst angeben:

function TService1DM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  Result := TJService.JavaClass.START_STICKY;
end;

Weitere Informationen finden Sie unter Service Lifecycle (EN).

Gebundener Dienst

Rufen Sie für einen gebundenen Dienst BindService('<Dienstname>') auf, um an den Dienst zu binden, damit Sie die Interaktion damit beginnen können, und rufen Sie UnBindService auf, um die Bindung an diesen Dienst aufzuheben.

Weitere Informationen finden Sie unter Bound Services (EN).

Methoden "BindService" und "UnBindService"

Wenn die Hauptanwendung BindService('<Dienstname>') aufruft, erhält die Verbindungsvariable einen Zeiger auf die Speicheradresse, an der der Dienst ausgeführt wird.

Wenn Sie nach dem Herstellen der Verbindung mit einem bestimmten Dienst UnBindService aufrufen und es sich bei der Anwendung um die einzige an den Dienst gebundene Anwendung handelt, gibt der Dienst sich selbst frei. Berücksichtigen Sie, dass die Verbindungsvariable der Hauptanwendung weiterhin auf die gleiche Speicheradresse zeigt. Wenn Sie eine erneute Bindung an denselben Dienst herstellen, kann das einen Absturz der Hauptanwendung verursachen, weil die Speicheradresse des Dienstes ungültig sein könnte.

Es gibt zwei Möglichkeiten, diese Situation zu behandeln:

  • Vermeiden Sie die automatische Referenzzählung (ARC) mit dem Attribut [UnSafe].
  • Weisen Sie der Variable Nil zu, bevor Sie die Bindung des Dienstes aufheben.

Das Attribut [Unsafe] verwenden

  private
    { Private declarations }
    [Unsafe] Service1: TAndroidService1DM;

Ereignis "OnBind"

Wenn Sie BindService('<Dienstname>') für Ihre Anwendung aufrufen, wird das Ereignis OnBind für das Android-Dienst-Projekt ausgelöst. Die Methode OnBind gibt ein IBinder-Objekt zurück, das für die eigentliche Verwaltung der Verbindung mit dem Dienst zuständig ist.

Das Überschreiben der Methode OnBind verursacht, dass das Ereignis das IBinder-Objekt nicht zurückgibt, das die Hauptanwendung zum Erhalt des Datenmoduls von dem Dienst benötigt.

Zur Verwendung der Methode OnBind:

  • Geben Sie in der Methode OnBind das IBinder-Objekt zurück:
function TAndroidServiceDM.AndroidServiceBind(const Sender: TObject;
  const AnIntent: JIntent): JIBinder;
begin
  // .... User's code
  Result := GetBinder(Self);
end;

Siehe auch