*Ein Service ist eine Android-Anwendungskomponente, die Folgendes darstellt:

  1. Der Wunsch einer Anwendung, langwierige Operationen durchzuführen, ohne mit dem Benutzer zu interagieren.
  2. Eine Komponente zur Bereitstellung von Funktionen für andere Anwendungen.

Wann sollte ich einen "Service" verwenden?

Verwenden Sie einen Service, wenn Sie eine lang laufende Operation oder eine Aufgabe haben, die einen langen Lebenszyklus hat. Es ist ein gutes Design, dass lange laufende Operationen im Hintergrund ausgeführt werden.

Ein Beispiel ist eine Aufgabe zur Datensynchronisation im Hintergrund.

Bei dieser Art von Aufgabe können Sie einen "Dienst" erstellen, der regelmäßig oder nach Bedarf ausgeführt wird. Sie können einen Systemalarm verwenden.

Dann kann Ihr Service beendet werden, wenn die Aufgabe beendet ist.

Durch die Ausführung der Aufgabe im Hintergrund wird der Haupt-Thread davon befreit, diese Aufgaben zu erledigen, wodurch verhindert wird, dass die Benutzeroberfläche eingefroren wird, wenn eine intensive Aufgabe ausgeführt wird.

Obwohl wir auch innerhalb einer Activity einfach einen neuen Thread abspinnen können, ist es ein viel besserer und saubererer Weg, die Hintergrundoperationen an einen Service zu delegieren.

Wo läuft der Service?

Alle Android-Komponenten, einschließlich "Service", laufen im Haupt-Thread des Anwendungsprozesses.

Der Lebenszyklus von Service unterscheidet sich vom Lebenszyklus von Activity. Ersterer ist besser geeignet, um lang laufende Operationen zu handhaben als letzterer.

Sobald wir unsere langlaufenden Operationen in einen Thread im Hintergrund verschoben haben, können wir diesen Thread innerhalb des Service starten und behandeln.

Lang laufende Operationen, die keine Benutzerinteraktion erfordern, sind die besten Kandidaten für die Delegation an einen "Service".

Vorteile eines Service

  1. Ein Service bietet uns einen effizienteren Mechanismus, um lang laufende Operationen von der Benutzeroberfläche zu entkoppeln.

Beispiele für die Verwendung eines Service

(a). Dienste ohne Benutzereingabe
  1. Anwendungen, die das Netzwerk häufig nutzen, um nach Updates zu fragen.
  2. App zum Abspielen von Musik.
  3. Messaging-Anwendung.
(b). Dienste" mit Benutzereingabe
  1. Foto-Sharing-Anwendung.

Schnelle "Dienst"-Schnipsel und Anleitungen

1. Wie man einen Service startet

Im ersten Beispiel haben wir den Klassennamen erhalten:

    public static void startService(String className) {
        try {
            startService(Class.forName(className));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Im zweiten Beispiel haben wir die Klasse selbst und den Kontext angegeben:

   public static void startService(Class<?> cls, Context context) {
        Intent intent = new Intent(context, cls);
        context.startService(intent);
    }
2. Wie man einen Service stoppt

Nehmen wir an, Sie wollen einen Service stoppen und Sie haben den Klassennamen erhalten:

    public static boolean stopService(String className) {
        try {
            return stopService(Class.forName(className));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

Was ist, wenn Sie die Klasse selbst erhalten haben?

    public static boolean stopService(Class<?> cls, Context context) {
        Intent intent = new Intent(context, cls);
        return context.stopService(intent);
    }
3. Wie man einen Service bindet

Wir haben zwei Beispiele. Here's the first one:

    public static void bindService(String className, ServiceConnection conn, int flags) {
        try {
            bindService(Class.forName(className), conn, flags);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

dann das zweite Beispiel:

    public static void bindService(Class<?> cls, ServiceConnection conn, int flags,Context context) {
        Intent intent = new Intent(context, cls);
       context.bindService(intent, conn, flags);
    }
4. Wie man einen Service entbindet

    public static void unbindService(ServiceConnection conn,Context context) {
        context.unbindService(conn);
    }

5. Wie man alle laufenden Services erhält

Sie wollen alle laufenden Services im System ermitteln und deren Namen als Set zurückgeben.

    public static Set getAllRunningService(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningServiceInfo> info = activityManager.getRunningServices(0x7FFFFFFF);
        Set<String> names = new HashSet<>();
        if (info == null || info.size() == 0) return null;
        for (RunningServiceInfo aInfo : info) {
            names.add(aInfo.service.getClassName());
        }
        return names;
    }

Schnelle Dienst Beispiele

1. Wie man Songs in eine ArrayList in einem Service lädt

Wir muessen dies in einem thread im Hintergrund tun, da wir unsere Benutzeroberflaeche nicht einfrieren moechten.

Wir werden diese Lieder protokollieren, aber natürlich kann man sie auch in einer recyclerview oder listview darstellen und eine Klasse implementieren, um sie abzuspielen.

Beginnen wir mit der Definition eines Song-Objekts. Dies ist unsere Song-Bean-Klasse:

public final class Song {

    private String name;

    private String artist;

    private String coverUri;

    private long time;

    private String location;

    public String getName() {
        return name;
    }

    public Song setName(String name) {
        this.name = name;
        return this;
    }

    public String getArtist() {
        return artist;
    }

    public Song setArtist(String artist) {
        this.artist = artist;
        return this;
    }

    public String getCoverUri() {
        return coverUri;
    }

    public Song setCoverUri(String coverUri) {
        this.coverUri = coverUri;
        return this;
    }

    public long getTime() {
        return time;
    }

    public Song setTime(long time) {
        this.time = time;
        return this;
    }

    public String getLocation() {
        return location;
    }

    public Song setLocation(String location) {
        this.location = location;
        return this;
    }

    @Override
    public String toString() {
        return String.format("name = %s, artist = %s, location = %s",
                name,
                artist,
                location);
    }
}

Dann fahren wir fort, unseren Service zu erstellen.

Sie beginnen mit der Erstellung einer Klasse, die den Service implementiert:

public class ScanMusicService extends Service {...}

Wenn ein Service erstellt wird, wird normalerweise die onCreate() Lebenszyklusmethode vom System aufgerufen.

An dieser Stelle werden wir einen Thread starten, der unsere Songs scannt und sie in eine Array-Liste im Hintergrund Thread laden wird:

    @Override
    public void onCreate() {
        super.onCreate();

        new Thread(new Runnable() {
            @Override
            public void run() {
                ArrayList<Song> songs = scanSongs(ScanMusicService.this);
                LogUtils.d(songs);
                ToastUtils.showLongToast(songs.toString());
            }
        }).start();

    }

Die Methode scanSongs() wird für das Scannen und Füllen unserer Arrayliste mit Songs verantwortlich sein.

Hier ist die vollständige Klasse:

import android.app.Service;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.IBinder;
import android.provider.MediaStore;
import android.support.annotation.Nullable;

import com.jiangkang.tools.bean.Song;
import com.jiangkang.tools.utils.LogUtils;
import com.jiangkang.tools.utils.ToastUtils;

import java.util.ArrayList;

public class ScanMusicService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();

        new Thread(new Runnable() {
            @Override
            public void run() {
                ArrayList<Song> songs = scanSongs(ScanMusicService.this);
                LogUtils.d(songs);
                ToastUtils.showLongToast(songs.toString());
            }
        }).start();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    private ArrayList<Song> scanSongs(Context context) {
        ArrayList<Song> result = new ArrayList<>();
        ContentResolver resolver = context.getContentResolver();
        Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                null,
                null,
                null,
                null);
        if (cursor != null && !cursor.isClosed() && cursor.moveToFirst()) {
            while (cursor.moveToNext()) {
                String songName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
                String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                String location = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));

                Song song = new Song();
                song.setName(songName)
                        .setArtist(artist)
                        .setLocation(location);
                LogUtils.d(song.toString());
                result.add(song);
            }
        }
        return result;
    }
}

Und das ist die Klasse, die uns beim Laden von Songs hilft.

2. Wie man den System Download Manager und Service zum Herunterladen benutzt

Wir wollen sehen, wie man einen Service erstellt, der Daten mit dem System DownloadManager herunterladen kann.

Fangen wir gleich damit an. Zuerst erstellen wir einen androiden Service:

public class DownloadService extends Service {

Dann erstellen wir mehrere Klassen und Instanzfelder in dieser Klasse:

    private BroadcastReceiver receiver;
    private DownloadManager dm;
    private long enqueue;
    private String downloadUrl = "http://192.168.3.186/StaffAssistant.apk";
    private static String apkname = "StaffAssistant.apk";

Diese sind:

  1. BroadcastReceiver - unsere Broadcast-Empfänger-Instanz.
  2. DownloadManager - Unser System-Download-Manager.
  3. enqueue(long) - Die eindeutige Download-Aufgaben-ID, die vom System-Downloader zugewiesen wurde und mit der die Download-Aufgabe abgefragt oder bearbeitet werden kann.
  4. Download-URL" - Die URL, unter der die Apk heruntergeladen werden kann.
  5. ApK name - Name der Anwendung

Erinnern Sie sich, dass wir den Service erweitert haben und noch keine der Methoden implementiert haben, die wir überschreiben müssen. Hier ist eine:


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

Wir geben dort null zurück und gehen zu unserem onStartCommand() über.

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ....

Dort werden wir zuallererst unseren Download-URL-String über Intent erhalten.

Anschließend instanziieren wir unsere BroadcastReceiver-Klasse und überschreiben die Methode onReceive().

        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                install(context);
            }
        };

Innerhalb der Methode onReceive() können Sie sehen, dass wir die Methode install() aufrufen. Diese Methode ist eine eigene Methode, die wir erstellen werden, um unsere Anwendung zu installieren.

Außerhalb unserer onReceive() Methode werden wir unseren BroadcastReceiver registrieren, da es sich um eine Android Komponente handelt.

registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

Sie sehen deutlich, dass wir ihn programmatisch registriert haben, da wir ihn als anonyme Klasse erstellt haben.

Dann rufen wir die Methode startDownload() auf, eine weitere benutzerdefinierte Methode, die wir später erstellen werden.

startDownload ( downloadUrl );

Beachten Sie, dass dies eine Schreibberechtigung für die SD-Karte erfordert. Wenn Sie eine targetSDKVersion größer oder gleich 23 verwenden, können Sie dynamische Berechtigungen verwenden.

Schauen wir uns nun an, wie wir die App nach dem Herunterladen programmatisch installieren können.

Zuerst erstellen wir die Methode install(). Sie erhält ein Context-Objekt, das es uns ermöglicht, die Methode startActivity() aufzurufen.

    public static void install(Context context) {

Dann instanziieren wir eine java.io.File. Wir übergeben den Pfad, in dem wir die Datei erstellen, und den Dateinamen:

        File file = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                , apkname);

Dann erstellen wir ein Intent Objekt:

        Intent intent = new Intent(Intent.ACTION_VIEW);

Da die Activity nicht in der Activity Umgebung gestartet wird, setzen wir das folgende Label:

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Ob die Version über 7.0 liegt.

        if (Build.VERSION.SDK_INT >= 24) {

Anschließend rufen wir die Methode getUriForFile() der Klasse FileProvider auf. Dazu gehören:

  1. Context.
  2. Host-Adresse des Anbieters.
  3. Die zu installierende Datei.

            Uri apkUri =
                    FileProvider.getUriForFile(context, "com.hzecool.slhStaff.fileprovider", file);
            //Adding this sentence means temporarily authorizing the file represented by the Uri to the target application.
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(file),
                    "application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }

Dann kommen wir und überschreiben die onDestroy() Methode der Service Klasse. hier deregistrieren wir unseren BroadcastReceiver.

    @Override
    public void onDestroy() {
        unregisterReceiver(receiver);
        super.onDestroy();
    }

Schauen wir uns nun an, wie man herunterlädt.
Zuerst erstellen wir die Methode startDownload():

    private void startDownload(String downUrl) {

Zuerst holen wir den System DownloadManager:

        dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

Wir beginnen mit der Instanziierung der Klasse DownloadManager.Request. Während der Instanzierung analysieren wir unsere Download-Url mit der Methode parse() der Klasse Uri und übergeben sie an unsere Klasse Request:

        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downUrl));

Dann setzen wir unseren Mime-Typ oder den Typ der Datei als APK mit der setMimeType() Methode:

        request.setMimeType("application/vnd.android.package-archive");

Dann setzen wir das Ziel für unseren Download mit der Methode setDestinationInExternalPublicDir(). In diesem Fall verwenden wir das Download-Verzeichnis.

        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkname);

Wir rufen die setNotificationVisibility() auf, um anzugeben, ob eine Benachrichtigung angezeigt werden soll, wenn der Download abgeschlossen ist.

        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

Dann setzen wir den Titel

        request.setTitle("Download new version");

Zu guter Letzt führen wir den Download durch und geben die eindeutige ID der Aufgabe zurück

        enqueue = dm.enqueue(request);
    }
}

Hier ist der vollständige Code für den Service:

import android.app.DownloadManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;

import java.io.File;

public class DownloadService extends Service {
    private BroadcastReceiver receiver;
    private DownloadManager dm;
    private long enqueue;
    private String downloadUrl = "http://192.168.3.186/StaffAssistant.apk";
    private static String apkname = "StaffAssistant.apk";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        downloadUrl = intent.getStringExtra("downloadUrl");
        if (TextUtils.isEmpty(downloadUrl)) {
            apkname = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1, downloadUrl.length());
        }
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                install(context);

            }
        };
        registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        startDownload(downloadUrl);
        return Service.START_STICKY;
    }

    public static void install(Context context) {
        File file = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                , apkname);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= 24) {
            Uri apkUri =
                    FileProvider.getUriForFile(context, "com.hzecool.slhStaff.fileprovider", file);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(file),
                    "application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(receiver);
        super.onDestroy();
    }

    private void startDownload(String downUrl) {
        dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downUrl));
        request.setMimeType("application/vnd.android.package-archive");
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkname);
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        request.setTitle("Download new version");
        enqueue = dm.enqueue(request);
    }
}

Full Service Examples

Schauen wir uns die vollständigen Standalone-Beispiele an, die Sie herunterladen und ausführen können.

1. Einfaches gebundenes Service Beispiel

MainActivity.java

Dies ist die Hauptaktivität. Diese Klasse leitet sich von der AppCompatActivity ab und ist für unsere Benutzeroberfläche verantwortlich.

Hier sind einige API-Definitionen, die Sie vielleicht nicht kennen:

(a). SeviceConnection

Dies ist eine Schnittstelle, die sich im Paket android.content befindet und dazu dient, den Zustand eines Anwendungsdienstes zu überwachen.

(b). IBinder

IBinder ist die Basisschnittstelle für remotable Objekte, das Kernstück eines leichtgewichtigen Remote-Procedure-Call-Mechanismus, der für hohe Leistung bei prozessinternen und prozessübergreifenden Aufrufen entwickelt wurde.

package com.example.ankitkumar.boundservice;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    BoundService myService;
    boolean isBound = false;

    TextView currenttime, time, date;
    Button btn_start_service;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Set the activity content from a layout resource
        setContentView(R.layout.activity_main);
        time = (TextView) findViewById(R.id.tv_time);
        date = (TextView) findViewById(R.id.tv_date);
        currenttime = (TextView) findViewById(R.id.textView_current_time);
        btn_start_service = (Button) findViewById(R.id.button_start_service);
        Intent intent = new Intent(MainActivity.this, BoundService.class);

        /*
        Connect to an application service
        Automatically create the service as long as the binding exists
        */
        bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
    }

    public void getcurrenttime(View view) {
        currenttime.setText(myService.getCurrentTime());
        time.setVisibility(View.VISIBLE);
        date.setVisibility(View.VISIBLE);
    }

    //Setting Up BoundService
    private ServiceConnection myConnection = new ServiceConnection() {

        //Service Connected
        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            BoundService.MyLocalBinder binder = (BoundService.MyLocalBinder) service;
            myService = binder.getService();
            isBound = true;
        }

        //Service is Disconnected
        public void onServiceDisconnected(ComponentName arg0) {
            isBound = false;
        }

    };

}

BoundService.java

Dies ist unsere "Service"-Subklasse.

package com.example.ankitkumar.boundservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class BoundService extends Service {

    //Base interface for a remotable object, the core part of a lightweight remote procedure call mechanism
    private final IBinder myBinder = new MyLocalBinder();

    //Binding Service
    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return myBinder;
    }

    //Formatting and parsing dates in a locale-sensitive manner
    public String getCurrentTime() {
        SimpleDateFormat dateformat = new SimpleDateFormat("HH:mm:ss  dd/MMM/yyyy", Locale.US);
        return (dateformat.format(new Date()));
    }

    class MyLocalBinder extends Binder {
        BoundService getService() {
            return BoundService.this;
        }
    }
}

activity_main.xml

Das Hauptlayout von activity.

<?xml version="1.0" encoding="UTF-8"?>

<RelativeLayout
    tools_context="com.example.ankitkumar.boundservice.MainActivity" android_background="#efedef" android_layout_height="match_parent" android_layout_width="match_parent" android_id="@+id/activity_main"  >

<TextView
    android_layout_height="wrap_content" android_layout_width="100sp" android_id="@+id/tv_time" android_visibility="gone" android_textStyle="bold" android_textSize="18sp" android_textColor="@android:color/background_dark" android_text="@string/time" android_gravity="end" android_fontFamily="sans-serif-condensed" android_layout_marginTop="40sp"/>

<TextView
    android_layout_height="wrap_content"
     android_layout_width="140sp" android_id="@+id/tv_date" android_visibility="gone" android_textStyle="bold" android_textSize="18sp" android_textColor="@android:color/background_dark" android_text="@string/date" android_gravity="bottom" android_fontFamily="sans-serif-condensed" android_layout_marginTop="40sp" android_layout_alignParentRight="true" android_layout_alignParentEnd="true"/>

<TextView
    android_layout_height="wrap_content" android_layout_width="match_parent" android_id="@+id/textView_current_time" android_textSize="36sp" android_textColor="#ee6f64" android_gravity="center" android_fontFamily="sans-serif-condensed" android_layout_marginTop="70dp" android_hint="@string/time_label" android_layout_centerHorizontal="true"/>

<Button
    android_background="#e54048" android_layout_height="60sp" android_layout_width="200sp" android_id="@+id/button_start_service" android_textStyle="bold" android_textSize="18sp" android_textColor="#ffff" android_text="@string/show_time" android_fontFamily="sans-serif-condensed" android_onClick="getcurrenttime" android_layout_centerInParent="true"/>

</RelativeLayout>

Laden Sie den folgenden Code herunter.

No. Ort Link
1. GitHub Download
2. GitHub Durchsuchen
2. GitHub Original Creator: @AnkitKumar111

Android IntentService

public abstract class IntentService
extends Service
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.app.Service
↳ android.app.IntentService

IntentService ist eine Basisklasse für Services, die asynchrone Anfragen (ausgedrückt als Intents) bei Bedarf verarbeiten. Clients senden Anfragen durch startService(Intent)-Aufrufe; der Service wird nach Bedarf gestartet, bearbeitet jeden Intent der Reihe nach mit einem Worker Thread und stoppt sich selbst, wenn er keine Arbeit mehr hat.

Dieses "Warteschlangen-Prozessor"-Muster wird üblicherweise verwendet, um Aufgaben vom Haupt-Thread einer Anwendung zu entlasten. Die Klasse IntentService existiert, um dieses Muster zu vereinfachen und sich um die Mechanik zu kümmern. Um sie zu verwenden, erweitern Sie IntentService und implementieren onHandleIntent(Intent). Der IntentService empfängt die Intents, startet einen Thread und stoppt den Service nach Bedarf.

Alle Anfragen werden von einem einzigen Worker-Thread bearbeitet - sie können so lange wie nötig dauern (und werden die Hauptschleife der Anwendung nicht blockieren), aber es wird immer nur eine Anfrage bearbeitet.

Categorized in: