web-dev-qa-db-fra.com

Exécuter les messages du gestionnaire dans un fil d’arrière-plan

Je veux exécuter un Runnable dans un fil d’arrière-plan. Je veux utiliser Handler parce que c'est pratique pour les retards . Ce que je veux dire, c'est

handler.post(runnable, delay);

runnable devrait être exécuté dans background Thread .. Est-il possible de créer un tel gestionnaire?

P.S. Je sais comment le faire avec une classe personnalisée qui étend Thread, mais cela nécessite un peu plus d'effort de codage que de le faire avec le gestionnaire. Donc, s'il vous plaît ne postez pas d'autres solutions ou quelque chose comme

handler.post(new Runnable() {
    @Override
    public void run() {
        new Thread() {
            @Override
            public void run() {
                //action
            }
        }.start();
    }
});

Je me demande si Handler peut le faire de manière "propre".

32
Yaroslav Mytkalyk

Vous pouvez simplement faire ceci:

private Handler mHandler = null;

private HandlerThread mHandlerThread = null;

public void startHandlerThread(){
    mHandlerThread = new HandlerThread("HandlerThread");
    mHandlerThread.start();
    mHandler = new Handler(mHandlerThread.getLooper());
}

Puis invoquer avec:

handler.postDelayed(new Runnable(),1000);
63

Vous pouvez essayer quelque chose comme ça

    private void createHandler() {
        Thread thread = new Thread() {
            public void run() {
                Looper.prepare();

                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                       // Do Work
                        handler.removeCallbacks(this);
                        Looper.myLooper().quit();
                   }
                }, 2000);

                Looper.loop();
            }
        };
        thread.start();
    }
7
Ayman Mahgoub

Vous pouvez configurer un Looper dans un fil d’arrière-plan en utilisant Looper.prepare() et Looper.loop.

5
Yuichi Araki

Vous ne comprenez pas ce que vous voulez dire par Handler.

Il semble que vous ayez besoin d’un thread alimenté par une file d’alimentation. Vous auriez probablement intérêt à examiner Executors ici mais voici une simple paire de deux threads qui communiquent via une file d'attente.

public class TwoThreads {
  public static void main(String args[]) throws InterruptedException {
    System.out.println("TwoThreads:Test");
    new TwoThreads().test();
  }
  // The end of the list.
  private static final Integer End = -1;

  static class Producer implements Runnable {
    final Queue<Integer> queue;

    public Producer(Queue<Integer> queue) {
      this.queue = queue;
    }

    @Override
    public void run() {
      try {
        for (int i = 0; i < 1000; i++) {
          queue.add(i);
          Thread.sleep(1);
        }
        // Finish the queue.
        queue.add(End);
      } catch (InterruptedException ex) {
        // Just exit.
      }
    }
  }

  static class Consumer implements Runnable {
    final Queue<Integer> queue;

    public Consumer(Queue<Integer> queue) {
      this.queue = queue;
    }

    @Override
    public void run() {
      boolean ended = false;
      while (!ended) {
        Integer i = queue.poll();
        if (i != null) {
          ended = i == End;
          System.out.println(i);
        }
      }
    }
  }

  public void test() throws InterruptedException {
    Queue<Integer> queue = new LinkedBlockingQueue<>();
    Thread pt = new Thread(new Producer(queue));
    Thread ct = new Thread(new Consumer(queue));
    // Start it all going.
    pt.start();
    ct.start();
    // Wait for it to finish.
    pt.join();
    ct.join();
  }
}
0
OldCurmudgeon