2

У меня есть этот код, который является активностью, когда при запуске будет проверяться подключение к Интернету, если есть соединение, тогда жизнь идет на. Еще раз появится диалоговое окно, чтобы включить соединение. Однако я сделал поток, который каждые 10 секунд проверяет на соединение, и в случае потери связи он снова отобразит диалоговое окно.Еще один «Не удается создать обработчик внутри потока, который не вызвал Looper.prepare()», тема

package greensmartcampus.eu.smartcampususerfeedbackapp; 

import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.os.Bundle; 
import android.provider.Settings; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.Toast; 

import java.net.InetAddress; 


public class HomeScreen extends AbstractPortraitActivity { 

    private static final int WIFI_REQUEST_CODE = 1; 
    private boolean networkSettingsDialogOpened = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_home_screen); 
     this.runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       while (!HomeScreen.this.isInternetAvailable()) { 
        if (!networkSettingsDialogOpened) 
         HomeScreen.this.createNetErrorDialog(); 
        try { 
         Thread.sleep(10000); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }); 
    } 

(...) 

    private boolean isInternetAvailable() { 
     try { 
      final InetAddress ipAddr = InetAddress.getByName("google.com"); 
      if (ipAddr.equals("")) { 
       return false; 
      } else { 
       return true; 
      } 
     } catch (Exception e) { 
      return false; 
     } 
    } 

    private void createNetErrorDialog() { 
     networkSettingsDialogOpened = true; 
     final AlertDialog.Builder builder = new AlertDialog.Builder(this); 
     builder.setMessage("You need a network connection to use this application. Please turn on mobile network or Wi-Fi in Settings.") 
       .setTitle("Unable to connect") 
       .setCancelable(false) 
       .setPositiveButton("Settings", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           Intent i = new Intent(Settings.ACTION_WIRELESS_SETTINGS); 
           startActivityForResult(i, WIFI_REQUEST_CODE); 
          } 
         } 
       ) 
       .setNegativeButton("Cancel", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           HomeScreen.this.finish(); 
          } 
         } 
       ); 
     final AlertDialog alert = builder.create(); 
     alert.show(); 
    } 

    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == WIFI_REQUEST_CODE) { 
      if (resultCode == RESULT_OK) { 
       networkSettingsDialogOpened = false; 
       Toast.makeText(HomeScreen.this, "Returned Ok", 
         Toast.LENGTH_LONG).show(); 
      } 
      if (resultCode == RESULT_CANCELED) { 
       networkSettingsDialogOpened = false; 
       Toast.makeText(HomeScreen.this, "Returned Canceled", 
         Toast.LENGTH_LONG).show(); 
      } 
     } 
    } 
} 

Однако я получаю следующее сообщение об ошибке:

02-03 18:13:14.525 2683-2699/greensmartcampus.eu.smartcampususerfeedbackapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-193 
    Process: greensmartcampus.eu.smartcampususerfeedbackapp, PID: 2683 
    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
      at android.os.Handler.<init>(Handler.java:200) 
      at android.os.Handler.<init>(Handler.java:114) 
      at android.app.Dialog.<init>(Dialog.java:108) 
      at android.app.AlertDialog.<init>(AlertDialog.java:125) 
      at android.app.AlertDialog$Builder.create(AlertDialog.java:967) 
      at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.createNetErrorDialog(HomeScreen.java:97) 
      at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen.access$200(HomeScreen.java:15) 
      at greensmartcampus.eu.smartcampususerfeedbackapp.HomeScreen$1.run(HomeScreen.java:29) 

Примечание: Line 97 является один, содержащий:

final AlertDialog alert = builder.create(); 

Я гугле много, я уже с помощью клише ответ runOnUiThread, но это не исправить.

Что мне не хватает?

ответ

2

То, как вы проверяете Интернет, я думаю, вы заставляете свой поток пользовательского интерфейса спать. Вы должны сделать это так.

Создайте один обработчик и Thread работает флаг:

Handler mHandler = new Handler(); 
boolean isRunning = true; 

Затем используйте эту нить из вашего OnCreate() метод:

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     while (isRunning) { 
      try { 
       Thread.sleep(10000); 
       mHandler.post(new Runnable() { 
        @Override 
        public void run() { 
         if(!HomeScreen.this.isInternetAvailable()){ 
          if (!networkSettingsDialogOpened) 
           HomeScreen.this.createNetErrorDialog(); 
         } 
        } 
       }); 
      } catch (Exception e) { 
      } 
     } 
    } 
    }).start(); 

Изменить этот метод немного

private boolean isInternetAvailable() { 
    try { 
     final InetAddress ipAddr = InetAddress.getByName("google.com"); 
     if (ipAddr.equals("")) { 
      return false; 
     } else { 
      isRunning = true; 
      return true; 
     } 
    } catch (Exception e) { 
     return false; 
    } 
} 
+0

Оба ответа решают мою проблему, как я могу выбрать ее как правильный ответ для этой темы. Могу ли я как-то выбрать оба ответа как * winners *? – PedroD

+0

Нет, вы можете выбрать только один! Вы можете пойти за кем угодно. – Rohit5k2

+0

Я не могу. Я научился очень полезным способам решения этих будущих проблем здесь, оба ответа - правильный ответ ... Может быть, мы можем бросить монету. Но это все еще несправедливо ... – PedroD

2

You не может вызвать Thread.sleep() из кода, который работает в потоке пользовательского интерфейса. Это ваш код:

this.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      while (!HomeScreen.this.isInternetAvailable()) { 
       if (!networkSettingsDialogOpened) 
        HomeScreen.this.createNetErrorDialog(); 
       try { 
        Thread.sleep(10000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }); 

Вы шутите нужно запустить битый код, который показывает Dialog в потоке пользовательского интерфейса. Попробуйте это вместо:

new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (!HomeScreen.this.isInternetAvailable()) { 
       if (!networkSettingsDialogOpened) 
        // Show the Dialog on the UI thread 
        HomeScreen.this.runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          HomeScreen.this.createNetErrorDialog(); 
         } 
        }); 
       try { 
        Thread.sleep(10000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }).start(); 
+0

Оба ответа решают мою проблему, как я могу выбрать ее как правильный ответ для этой темы. Могу ли я как-то выбрать оба ответа как * winners *? – PedroD

+0

Нет. Вы можете выбрать только один. Просто выберите один. Я не буду обижаться. –

+0

Я не могу. Я научился очень полезным способам решения этих будущих проблем здесь, оба ответа - правильный ответ ... Может быть, мы можем бросить монету. Но это все еще несправедливо ... – PedroD

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

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