Frage

In diesem Beispiel aus der Dokumentation (https://developer.android.com/guide/components/services.html#extendingservice), wir verwenden die "Looper" eines Threads und verwenden ihn in der Serviceklasse, und dann funktioniert der Dienst so, als ob er in einem separaten Thread wäre?

public class HelloService extends Service {
  private Looper mServiceLooper;
  private ServiceHandler mServiceHandler;

  // Handler that receives messages from the thread
  private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }
      @Override
      public void handleMessage(Message msg) {
          // Normally we would do some work here, like download a file.
          // For our sample, we just sleep for 5 seconds.
          long endTime = System.currentTimeMillis() + 5*1000;
          while (System.currentTimeMillis() < endTime) {
              synchronized (this) {
                  try {
                      wait(endTime - System.currentTimeMillis());
                  } catch (Exception e) {
                  }
              }
          }
          // Stop the service using the startId, so that we don't stop
          // the service in the middle of handling another job
          stopSelf(msg.arg1);
      }
  }

  @Override
  public void onCreate() {
    // Start up the thread running the service.  Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block.  We also make it
    // background priority so CPU-intensive work will not disrupt our UI.
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();

    // Get the HandlerThread's Looper and use it for our Handler 
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

      // For each start request, send a message to start a job and deliver the
      // start ID so we know which request we're stopping when we finish the job
      Message msg = mServiceHandler.obtainMessage();
      msg.arg1 = startId;
      mServiceHandler.sendMessage(msg);

      // If we get killed, after returning from here, restart
      return START_STICKY;
  }

  @Override
  public IBinder onBind(Intent intent) {
      // We don't provide binding, so return null
      return null;
  }

  @Override
  public void onDestroy() {
    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); 
  }
}

Vielen Dank

War es hilfreich?

Lösung

Der Thread (a HandlerThread) wird in begonnen in onCreate, wenn du anrufst thread.start();, Dann erhalten Sie einen Hinweis auf die Looper von diesem Thread (nur einer Looper wird per erstellt HandlerThread) um a zu erstellen Handler und die Handler wird verwendet, um Nachrichten an den Thread zu veröffentlichen. Das Looper ist das Objekt, das auf die Nachrichten in a wartet while(true) Schleife.

Jedes Mal, wenn ein Befehl an die gesendet wird Service, das Service veröffentlicht eine Nachricht an die HandlerThread durch die Handler.

Ein genauerer Blick auf den Quellcode hilft Ihnen, besser zu verstehen, wie alles funktioniert. Es gibt einen Excelente -Beitrag darüber Handlers und Loopers at Square Engineering Blog - Eine Reise auf dem Android -Haupt -Thread - Teil 1.

Sie können auch eine verwenden Intentservice Um Ihre eigenen Threads zu vermeiden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top