2013-07-28 16 views
5

W mojej aplikacji wyświetlam okno dialogowe podczas długotrwałego procesu w tle, który jest modalny.
To okno dialogowe jest ignorowane, gdy Android powraca z zadania w tle.Sprawdź, czy okno dialogowe można bezpiecznie odrzucić.

final ProgressDialog progressDialog = ProgressDialog.show(activity, "", "Doing something long running", true, true); 

new Thread(new Runnable() { 
    public void run() { 
     someLongRunningCode(); // (not using AsyncTask!) 

     activity.runOnUiThread(new Runnable() { 
      public void run() { 
       progressDialog.dismiss(); 
      } 
     }); 
    } 
}).start(); 

Teraz jednak, gdy użytkownik obraca urządzenie podczas jego proces nadal działa w tle aktywność jest odtworzona, a tym samym progressdialog zostaje oderwane od działalności.
Po długim procesie, Android oczywiście próbuje ukryć (teraz odłączone) okno dialogowe postępu, które następnie powoduje wyjątek: java.lang.IllegalArgumentException: View not attached to window manager.
Czy istnieje sposób sprawdzenia, czy można bezpiecznie zamknąć okno dialogowe?

Edycja: A może jeszcze lepiej, czy istnieje sposób na dołączenie istniejącego okna dialogowego do nowo utworzonego działania?
Nowe, sklonowane okno dialogowe również będzie w porządku.

Odpowiedz

3

Po prostu złap wyjątek i zignoruj ​​go. Decyzja Androida o ponownym uruchomieniu działania w trybie rotacji powoduje, że wątki mają kilka dziwnych wyjątków. Jednak pożądanym rezultatem końcowym nie jest wyświetlenie okna dialogowego. Jeśli przechwycisz wyjątek, żadne okno dialogowe nie zostanie wyświetlone. Więc jesteś dobry.

Jeśli nie korzystasz z oddzielnego układu/rysunków dla krajobrazu i portretu, możesz po prostu zastąpić configChange w swoim manifeście dla działania, aby nie zniszczyć działania (nadal będzie poprawnie obracać i zmieniać rozmiar dla ciebie)). W ten sposób pojawi się to samo okno dialogowe i nie powinieneś otrzymywać wyjątku. Inna opcja wymagałaby wiele pracy wokół obiektów OnSaveInstanceState i onRestoreInstanceState, a trzeba by bardzo uważać na problemy z synchronizacją, jeśli wątek faktycznie zakończy się w tym czasie. Całe odtworzone działanie na temat pomysłu rotacji nie działa dobrze w przypadku wielowątkowości.

+0

Właściwie najlepszym rozwiązaniem byłaby możliwość dołączenia istniejącego okna dialogowego do nowo utworzonej aktywności, ponieważ zadanie może nadal działać. Czy jest jakiś sposób na zrobienie tego? Również zaktualizowałem moje pytanie, aby to odzwierciedlić. – PureSpider

+1

Jeśli nie korzystasz z osobnego układu/rysunków dla krajobrazu i portretu, możesz po prostu zastąpić configChange w swoim manifeście dla działania, aby nie zniszczyć działania (nadal będzie poprawnie obracać i zmieniać rozmiar dla ciebie). Inna opcja wymagałaby wiele pracy wokół obiektów OnSaveInstanceState i onRestoreInstanceState, a trzeba by bardzo uważać na problemy z synchronizacją, jeśli wątek faktycznie zakończy się w tym czasie. –

+0

Ta metoda jest odradzana przez Google'a ... dlaczego? – PureSpider

0
if (progressDialog != null) { 
    progressDialog.dismiss(); 
} 
+0

Oczywiście progressDialog nie ma wartości null, nawet po odłączeniu od okna. W przeciwnym razie dostanę NPE, prawda? – PureSpider

+4

tak, masz rację. moja wina: –