2015-04-08 5 views
0

У меня есть этот код:Использование темы в Android для отправки сообщения

if (value) { 
      thread = new Thread() { 
       @Override 
       public void run() { 
        try { 
         while (!isConnected()) { 
          synchronized (this) { 
           wait(3000); 
          } 
         } 
        } catch (InterruptedException ex) { 
        } 

        if(wifiManager.isWifiEnabled()){ 
         sendMessageWidget(); 
        } else { 
         showWifiSettingsAlert(); 
        } 
       } 
      }; 

      thread.start(); 
     } 

Я хочу, чтобы мое приложение, чтобы ждать, пока клиент API Google не подключен, и чем отправить сообщение.

Код для метода IsConnected является:

Но я получаю сообщение об ошибке: NullPointerException: Невозможно создать обработчик внутри потока, который не называется Looper.prepare(), и он говорит, что ошибка где-то идентификатор showWifiSettingsAlert()

вот код:

public void showWifiSettingsAlert() { 
     AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity()); 

     // Setting Dialog Title 
     alertDialog.setTitle("Location accuracy tips"); 

     // Setting Dialog Message 
     alertDialog 
       .setMessage("You can improve the accuracy of your location by turning on\n- Wi-Fi"); 

     // On pressing Settings button 
     alertDialog.setPositiveButton("Turn on", 
       new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         wifiManager.setWifiEnabled(true); 
//      Posalji poruke al pre toga jos jednom azuriraj 
//      lokaciju al ako je pozvana aplikacija iz widgeta 
         if (value) { 
          sendMessageWidget(); 
         } 
        } 
       }); 

     // on pressing cancel button 
     alertDialog.setNegativeButton("Cancel", 
       new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         wifiManager.setWifiEnabled(false); 

         // Posalji poruke al pre toga jos jednom azuriraj 
         // lokaciju al ako je pozvana aplikacija iz widgeta 
         if (value) { 
          sendMessageWidget(); 
         } 
        } 
       }); 

     // Showing Alert Message 
     alertDialog.show(); 
    } 

Я хочу, если Wi-Fi не включен, пользователь т o выбрать включить это или нет, но в любом случае сообщение должно быть отправлено ... можете ли вы помочь?

+0

Потому что вы пытаетесь создать или обновить приложения Вид из рабочего потока и андроид не допускал, что, потому что вы должны вызвать вид кода, связанного в главном Application UI Thread only, так как я не знаю, какие коды в 'sendMessageWidget();' поэтому просто поместите 'showWifiSettingsAlert();' в 'runOnUiThread()'. – user370305

+0

Сделайте это с помощью Handler или используйте runOnUiThread, Проверить http://stackoverflow.com/a/9110251/3530653 –

+0

sendMessageWidget просто отправляет сообщение от виджета, ничего особенного – P3P5

ответ

0

Поскольку вы не можете коснуться пользовательского интерфейса из потока, отличного от основного потока, вы должны опубликовать эти изменения обратно в поток пользовательского интерфейса и его петлителя и связанных с ними обработчики. Вы можете сделать это явно, создав обработчик, связанный с потоком пользовательского интерфейса (который будет работать в любом месте, так как Looper.getMainLooper() статический вызов), такие как:

if (value) { 
      Handler uiCallback = new Handler(Looper.getMainLooper()); 
      thread = new Thread() { 
       @Override 
       public void run() { 
        try { 
         while (!isConnected()) { 
          synchronized (this) { 
           wait(3000); 
          } 
         } 
        } catch (InterruptedException ex) { 
        } 

        uiCallback.post(new Runnable() { 
         @Override public void run() { 
          if(wifiManager.isWifiEnabled()){ 
           sendMessageWidget(); 
          } else { 
           showWifiSettingsAlert(); 
          } 
         } 
        }); 

       } 
      }; 

      thread.start(); 
     } 

Или вместо того, чтобы использовать обработчик на всех, вы можете обернуть часть в методе run() в runOnUiThread(), если вы находитесь в деятельности, которая делает то же самое.

Следует обратить внимание, что на самом деле вам не нужно использовать нити. Если вы следуете примеру: https://developer.android.com/google/auth/api-client.html, вы обнаружите, что, выполнив ConnectionCallbacks, OnConnectionFailedListener, вы можете позвонить mGoogleApis.connect() из onStart() активности и когда он подключится или не выполнит соответствующий обратный вызов, будет выполняться в вызывающем потоке. Например,

@Override 
public void onConnected(Bundle connectionHint) { 
    if(wifiManager.isWifiEnabled()){ 
     sendMessageWidget(); 
    } else { 
     showWifiSettingsAlert(); 
    } 
} 

Достигает то же самое ...

+0

Работает отлично, спасибо. – P3P5

+0

Нет проблем, 'Обработчик h = новый обработчик (Looper.getMainLooper()) 'это удобный трюк, когда вам нужно вернуться к основному потоку :) –

+0

Я понял, спасибо :) – P3P5

0

Вы используете mGoogleApiClient.connect();, который является асинхронным методом, в потоке, и это запрещено.

Вы можете попробовать использовать вместо runOnUiThread:

runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        // TODO Auto-generated method stub 
        //do your stuff here 
       } 
      }); 
+0

Вы можете полностью называть это из любого потока: что он асинхронный просто означает, что он вернется, не блокируя текущий поток от выполнения до тех пор, пока он не будет подключен. Технически операционная система должна обрабатывать обратный вызов соответствующим образом - то есть дождаться, когда будет вызван обратный вызов; то ему вообще не придется беспокоиться о заправке. Но это был не его первоначальный вопрос. –

+0

Ваши работы также, спасибо. – P3P5

Смежные вопросы