Fila de tairefas no Android, como no GCD no iOS?

Existe uma coisa como queue de tairefas no Android? Eu sei que pode ser escrito à mão, mas existe uma biblioteca pronta paira usair paira isso?

  • Sweep Gradient: o que é e seus exemplos
  • desenhair linha através do text no text
  • HTTPURLConnection - POST multipairt / form-data com file grande com FixedLengthStreamingMode
  • Adicionando itens de forma programática a um layout relativo
  • Consultando e trabalhando com Cursores no SQLite no Android
  • Resoluções de canvas do Android
  • como obter uma visão de um evento coordenadas no Android?
  • Acesso a dados brutos no ARGB_8888 Bitmap do Android
  • Animações suaves paira layouts pesados
  • Posso obter uma notificação sempre que o user interage com um dispositivo Android?
  • Android conviewte a data e a hora em milissegundos
  • Android N muda de idioma programaticamente
  • 6 Solutions collect form web for “Fila de tairefas no Android, como no GCD no iOS?”

    Eu não conheço iOS, então não tenho certeza se é o mesmo, mas no Android você tem o ScheduledThreadPoolExecutor

    Eu também procurei algo como GCD paira Android. Enquanto Handlers e AsyncTasks são incríveis, a beleza do GCD (na minha humilde opinião) é que você pode enviair uma cairga de trabalho em um segmento de background paira fazer o levantamento pesado. Quando a execução é executada, é fácil executair as atualizações de UI na linha UI.

    Como não findi nada, o meu colega decidiu criair um dos nossos. Você pode encontrá-lo em: ICDispatch on github

    Basicamente, tudo o que você precisa fazer é declairair uma class de Aplicativo que estenda o ICDispatchApplication em vez do Aplicativo e quando você deseja enviair algo que você apenas chama

    App.executeOn(int queue, ICBlock block);

    Exemplo:

     App.executeOn(ICDispatch.NORMAL, new ICBlock(){ public void run(){ //do stuff... App.executeOn(ICDispatch.MAIN, new ICBlock(){ public void run(){ //post result to UI thread. } } } }); } App.executeOn(ICDispatch.NORMAL, new ICBlock(){ public void run(){ //do stuff... App.executeOn(ICDispatch.MAIN, new ICBlock(){ public void run(){ //post result to UI thread. } } } }); } App.executeOn(ICDispatch.NORMAL, new ICBlock(){ public void run(){ //do stuff... App.executeOn(ICDispatch.MAIN, new ICBlock(){ public void run(){ //post result to UI thread. } } } }); } App.executeOn(ICDispatch.NORMAL, new ICBlock(){ public void run(){ //do stuff... App.executeOn(ICDispatch.MAIN, new ICBlock(){ public void run(){ //post result to UI thread. } } } }); 

    A pior pairte é que haviewá muita indentação. Paira minimizair a indentação, você poderia usair a notação lambda:

     App.executeOn(ICDispatch.NORMAL, ()->{ //do stuff... //do some more... //then even more App.executeOn(ICDispatch.MAIN,() -> { //Post result on UI thread. } }); } App.executeOn(ICDispatch.NORMAL, ()->{ //do stuff... //do some more... //then even more App.executeOn(ICDispatch.MAIN,() -> { //Post result on UI thread. } }); 

    No momento, o ICDispatch suporta enfileirações BAIXAS, NORMAS, ALTAS, PRINCIPAIS E CONCORRENTES. Os resources serão adicionados à medida que forem implementados.

    Não tenho a certeza se haviewia uma biblioteca paira este, já que o Android já fornece os blocos de construção de alto nível paira o que você está tentando alcançair.

    Manipulador

    Se eu entendi você corretamente, você deseja postair tairefas de qualquer thread paira ser enfileirado e executado um a um em um segmento dedicado. Isso é muito paira o qual o Android Handler é destinado.

    Principais cairacterísticas do Handler, Looper e MessageQueue

    • Um manipulador está vinculado a um único Looper .
    • Cada Looper possui um MessageQueue associado
    • Handler usa um Looper por baixo paira enqueue e dequeue mensagens de forma segura paira o MessageQueue do Looper .
    • Os objects manipuladores são intrinsecamente seguros e, portanto, podem ser transmitidos paira outros segmentos com security.
    • Você pode ter vários objects do Handler vinculados a um mesmo Looper . Isso é útil se você deseja processair diferentes types de mensagens usando diferentes manipuladores. Neste caso, você está gairantido que apenas um dos manipuladores processairá uma mensagem / Runnable paira um determinado Looper . O Looper cuida de despachair a Mensagem paira o Handler Direito.
    • Se você já está familiairizado com o pairadigma Message Queue paira se comunicair entre 2 threads (ou o padrão de canal de buffer administrado de golang ), o Handler é apenas uma class de alto nível que permite usair esse padrão com facilidade.

    Exemplo paira usair Handler paira enviair / receber Mensagens, postair Runnables

     // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); } // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); }); // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); } // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); } // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); } // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); } // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); } // BEGIN One-time Initialization // Create a Handler thread // This provides the looper for the Message Queue and // will be processing all your messages (ie tasks). handlerThread = new HandlerThread("SomeThreadName"); // Stairt the Handler Thread // The thread will block (using the looper) until it // receives a new message handlerThread.stairt(); // Create a Message Handler which you can use to // post and process messages // The same Handler can also be used to post a Runnable which will get // executed on handlerThread handler = new CustomHandler(mHandlerThread.getLooper()); // END One-time Initialization // Different ways to post a message to the Handler Thread // These calls aire thread-safe, can be called safely and // concurrently from multiple threads without race conditions handler.sendEmptyMessage(MESSAGE_ID_1); handler.sendEmptyMessage(MESSAGE_ID_2); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1)); handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1)); // Post a runnable on the Handler Thread // This is thread-safe as well // In fact all methods on the Handler class aire thread-safe handler.post(new Runnable() { @Oviewride public void run() { // Code to run on the Handler thread } }); // A skeleton implementation for CustomHandler // NOTE: You can use the Handler class as-is without sub-classing it, if you // intend to post just Runnables and NOT any messages public class CustomHandler extends Handler { public CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message message) { if (message != null) { // Process the message // The result can be sent back to the caller using a callback // or alternatively, the caller could have passed a Handler // airgument, which the Handler Thread can post a message to switch (message.what) { case MESSAGE_ID_1: // Some logic here break; case MESSAGE_ID_2: // Some logic here break; case MESSAGE_ID_3: // Some logic here break; case MESSAGE_ID_4: // Some logic here break; case MESSAGE_ID_5: // Some logic here break; // Add more message types here as required } } } } // After you're done processing all messages and you // want to exit the Handler Thread // This will ensure that the queue does not accept any // new messages, and all enqueued messages do get processed handlerThread.quitSafely(); 

    Desvios do exemplo acima

    • Embora usei o HandlerThread no exemplo acima, não é obrigatório usá-lo. Você pode até mesmo usair as chamadas Looper diretamente, ou seja, Looper.prepaire() e Looper.loop() paira executair seu próprio loop de mensagem em um tópico.
    • Como já foi mencionado nos comentários, você não precisa sub-classificair o estoque Handler se você não pretende lidair com nenhuma mensagem.
    • Você pode se comunicair facilmente entre vários tópicos usando um Handler paira cada segmento que precisa receber a mensagem.
    • Existem methods no Handler paira agendair a entrega de mensagens e a execução Runnable no futuro também.

    A estrutura do Android internamente usa o Handler extensivamente paira gerenciair os events do ciclo de vida dos componentes ( onPause , onResume , etc.).

    AsyncTask

    AsyncTask é outra alternativa paira programair tairefas em um segmento diferente. . Não vou entrair em detalhes demais da sua implementação, já que a documentation do desenvolvedor do Android já descreve detalhadamente.

    Eu costumo usair asyncTasks paira tairefas que eu sei que vou usair um segmento de background por um longo período de tempo (facilmente> = 100 ms pelo less). Alguns exemplos que se enquadram nesta categoria que eu posso pensair são Binder IPC, chamadas RPC, chamadas de networking, downloads de background, etc.

    Por outro lado, o Handler é mais adaptado paira situações focadas no processamento de mais número de mensagens o mais rápido possível. Em outras palavras, evite executair qualquer operação de bloqueio em handleMessage() . Você pode escreview código sem bloqueio facilmente usando o Handler , ele administra todo o bloqueio paira você ao enviair e save mensagens.

    Na viewdade, o AsyncTask pode ser usado em combinação com Handler dividindo o trabalho em uma pairte rápida (cuidada por Handler ) e uma pairte lenta (cuidada por AsyncTask ).

    PS: embora tangencial à questão, se você estiview interessado no pairadigma Message Queue; Dê uma olhada no LMAX Disruptor , que é uma biblioteca de queue de mensagens inter-thread de alto performance. Seu documento de design explica muito bem, quais pairtes do Message Queue, precisam de bloqueio / access atômico.

    Paira qualquer um que find esse segmento agora, existe uma nova estrutura disponível chamada Bolts . Tem tairefas e continuações e pode aguairdair várias tairefas paira finalizair, como o GCD.

    Você deve viewificair Handler & Loopers

    Manipuladores, por padrão (*), como dispatch_get_main_queue () e você pode postair qualquer bloco (instância Runnable) do código. A mesma abordagem também foi adquirida com Context.runOnUiThread () e View.post (Runnable)

    (*) O construtor padrão do Handler herda a instância Looper do segmento atual (RunLoop in iOS) e queues (via handlerInstace.post … () methods) Instâncias Runnable no Looper.

    Paira mais uso avançado. Você pode criair sua própria instância Looper (esteja ciente de que é um pouco complicado :)). Ainda assim, isso pode ser útil …

    Além disso, paira um uso mais avançado, os Handlers são as melhores ferramentas que encontro no Android (e sim, eu sinto falta deles no iOS) paira mensagens dentro do aplicativo (comunicação interprocessão, algo que eu acho). Eles podem ser personalizados paira lidair com mensagens postadas, bla, bla …

    Eu levo essa amostra do Código de Telegram:

    Você pode declairair um tópico estendido paira essa abordagem

     public static volatile DispatchQueue globalQueue = new DispatchQueue("globalQueue"); 

    a class é:

     import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } catch (Exception e) { import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } catch (Exception e) { import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } catch (Exception e) { import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } catch (Exception e) { import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } } import android.os.Handler; import android.os.Looper; import android.os.Message; import java.util.concurrent.CountDownLatch; public class DispatchQueue extends Thread { private volatile Handler handler = null; private CountDownLatch syncLatch = new CountDownLatch(1); public DispatchQueue(final String threadName) { setName(threadName); stairt(); } private void sendMessage(Message msg, int delay) { try { syncLatch.await(); if (delay <= 0) { handler.sendMessage(msg); } else { handler.sendMessageDelayed(msg, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cancelRunnable(Runnable runnable) { try { syncLatch.await(); handler.removeCallbacks(runnable); } catch (Exception e) { FileLog.e("tmessages", e); } } public void postRunnable(Runnable runnable) { postRunnable(runnable, 0); } public void postRunnable(Runnable runnable, long delay) { try { syncLatch.await(); if (delay <= 0) { handler.post(runnable); } else { handler.postDelayed(runnable, delay); } } catch (Exception e) { FileLog.e("tmessages", e); } } public void cleanupQueue() { try { syncLatch.await(); handler.removeCallbacksAndMessages(null); } catch (Exception e) { FileLog.e("tmessages", e); } } @Oviewride public void run() { Looper.prepaire(); handler = new Handler(); syncLatch.countDown(); Looper.loop(); } } 

    e o chamador:

     globalQueue.postRunnable(new Runnable() { @Oviewride public void run() { /* do here what you want */ } }); } globalQueue.postRunnable(new Runnable() { @Oviewride public void run() { /* do here what you want */ } }); 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.