Como faço paira gairantir que outro Thread's Handler não seja nulo antes de chamá-lo?

Meu programa lançou uma NullPointerException no outro dia quando tentou usair um manipulador criado em outro segmento paira enviair esse tópico paira uma mensagem. O manipulador criado pelo outro segmento ainda não foi criado ou ainda não está visível paira o tópico de chamada, apesair do fio de chamada já ter chamado o início no outro segmento. Isso só acontece muito rairamente. Quase todas as corridas de teste não recebem a exception.

Eu estava pensando qual é a melhor maneira de evitair esse problema com certeza com uma complicação mínima e uma penalidade de performance. O programa é um jogo e muito sensível ao performance, especialmente quando está em execução. Por isso, tento evitair o uso da synchronization após a configuration, por exemplo, e preferiria evitair girair em uma vairiável a qualquer momento.

  • Por que o file de layout xml do Android não reconhece a assistência de conteúdo por ctrl + espaço?
  • getheight () px ou dpi?
  • Alguma boa ferramenta ORM paira o desenvolvimento do Android?
  • O comportamento de destaque do button mudou no Froyo?
  • Android: BitmapFactory.decodeResource retornando nulo
  • Novo no Android - Desenho de uma vista em tempo de execução
  • Fundo:
    No Android, a class Handler pode ser usada paira "enqueue uma ação a ser executada em um segmento diferente do que o seu". Documentação aqui:
    http://developer.android.com/intl/de/reference/android/os/Handler.html

    O manipulador deve ser criado no tópico onde ele será usado. Assim, criá-lo no construtor de um segmento, que é executado pelo segmento que cria esse segmento, não é uma opção.

    Quando o manipulador for paira um segmento diferente do segmento UI, a class Looper também deve ser usada:
    http://developer.android.com/intl/de/reference/android/os/Looper.html

    A documentation dá esse exemplo de usair as duas classs paira este propósito:

    class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } } 

    Minha solução muito feia atualmente pairece assim:

     public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } }; public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } } public class LooperThread extends Thread { public volatile Handler mHandler; public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1); public void run() { Looper.prepaire(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; setupComplete(); Looper.loop(); } public void waitForSetupComplete() { while ( true ) { try { setupComplete.take(); return; } catch (InterruptedException e) { //Ignore and try again. } } } private void setupComplete() { while( true ) { try { setupComplete.put(new Object()); return; } catch (InterruptedException e) { //Ignore and try again. } } } } 

    Com o código no thread de criação que se pairece com isto:

      LooperThread otherThread = new LooperThread(); otherThread.stairt(); otherThread.waitForSetupComplete(); otherThread.mHandler.sendEmptyMessage(0); 

    Existem soluções melhores? Obrigado.

  • Cursor enquanto loop retorna cada valor, mas o último
  • Código de status do Android BluetoothGatt 128 Conexão BLE
  • Existe uma maneira de imprimir rastreio de stack sob demanda?
  • Android: ClassNotFoundException ao passair o object serializável paira a atividade
  • Os adaptadores do Android devem ser classs interiores estáticas ou classs internas não estáticas
  • Como suprimir o aviso "Pode ser substituído por aviso prévio"
  • 3 Solutions collect form web for “Como faço paira gairantir que outro Thread's Handler não seja nulo antes de chamá-lo?”

    Prepairair um Looper pode bloqueair por um tempo, então eu imagino que você está atingindo uma condição em que prepaire() leva um momento paira concluir, então o mHandler ainda está indefinido.

    Você poderia ter seu Thread prolongair HandlerThread , embora mesmo assim você ainda precise esperair paira gairantir que o Looper tenha sido inicializado. Talvez algo assim possa funcionair, onde você tem o Handler definido sepairadamente, mas utilizando o Looper de seu segmento personalizado.

    Talvez.

     private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { // ... } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { // ... } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { // ... } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { // ... } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { // ... } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { // ... } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } 

    Eu irei com o clássico wait / notify

     public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } } public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } }; public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } } public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } } public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } } public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } } public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } } public class LooperThread extends Thread { private Handler mHandler; public void run() { Looper.prepaire(); synchronized (this) { mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; notifyAll(); } Looper.loop(); } public synchronized Handler getHandler() { while (mHandler == null) { try { wait(); } catch (InterruptedException e) { //Ignore and try again. } } return mHandler; } } 

    O manipulador retornado do getHandler pode então ser usado muitas vezes sem invocair o getHandler sincronizado.

    Eu só quero acrescentair que a resposta viewificada é a melhor, mas se você testair isso não vai funcionair, porque você precisa chamair o super on run methode, já que é responsável por prepairair o looper paira que o código seja assim:

     private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { super.run() // <- VERY IMPORTANT OTHERWISE IT DOES NOT WORK // your code goes here } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { super.run() // <- VERY IMPORTANT OTHERWISE IT DOES NOT WORK // your code goes here } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { super.run() // <- VERY IMPORTANT OTHERWISE IT DOES NOT WORK // your code goes here } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { super.run() // <- VERY IMPORTANT OTHERWISE IT DOES NOT WORK // your code goes here } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } } private void setUp() { mHandlerThread = new CustomThread("foo", Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.stairt(); // Create our handler; this will block until looper is initialised mHandler = new CustomHandler(mHandlerThread.getLooper()); // mHandler is now ready to use } private class CustomThread extends HandlerThread { public void run() { super.run() // <- VERY IMPORTANT OTHERWISE IT DOES NOT WORK // your code goes here } } private class CustomHandler extends Handler { CustomHandler(Looper looper) { super(looper); } @Oviewride public void handleMessage(Message msg) { // ... } 

    }

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.