2010-07-21 8 views
27

Mam IntentService, która pobiera niektóre pliki. Problemem jest to, że tworzę Toast wewnątrz IntentService jak tenToast stworzony w IntentService nigdy nie znika

Toast.makeText(getApplicationContext(), "some message", Toast.LENGTH_SHORT).show(); 

Toast nigdy nie zniknie zdarzenie gdybym zamknąć aplikację. Jedynym sposobem na zniszczenie go jest zabicie tego procesu.

Co robię źle?

+0

Nie ma powodu, nie tworzyć Toastu z usługi. Z [podręcznika dev powiadomień] (http://developer.android.com/guide/topics/ui/notifiers/toasts.html): > Jeśli utworzysz powiadomienie o toastu z usługi, pojawi się on przed działaniem obecnie w centrum uwagi. –

+0

To musi być złe, ponieważ nie działa, gdy testujesz go za pomocą IntentService. Rozwiązanie @ rony działa najlepiej. –

Odpowiedz

-8

Nie należy tworzyć Toast s z Service. Zamiast tego należy użyć wartości Notification.

+11

Niepoprawnie. od http://developer.android.com/guide/topics/ui/notifiers/toasts.html "Toast można tworzyć i wyświetlać z działania lub usługi". Nie działa, ponieważ "Usługa" działa na głównym wątku, natomiast "Intent service" działa na innym wątku. – Palani

+6

Samo zrobienie czegoś nie oznacza, że ​​powinieneś coś zrobić. Nie powinieneś tworzyć toastów z usługi. – Qberticus

+0

@Qberticus, czy możesz zaktualizować swoją odpowiedź, podając przykład kodu, w jaki sposób będzie używane powiadomienie? –

69

Problem polega na tym, że IntentService nie działa w głównym wątku aplikacji. musisz uzyskać Handler dla głównego wątku (w onCreate()) i opublikować Toast jako Runnable.

następujący kod powinien załatwić sprawę:

@Override 
public void onCreate() { 
    super.onCreate(); 
    mHandler = new Handler(); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 
    mHandler.post(new Runnable() {    
     @Override 
     public void run() { 
      Toast.makeText(MyIntentService.this, "Hello Toast!", Toast.LENGTH_LONG).show();     
     } 
    }); 
} 
+0

Handler jest abstrakcyjny – rkmax

+8

nie, nie jest. http://developer.android.com/reference/android/os/Handler.html – maysi

+5

@rkmax android studio z jakiegoś powodu domyślnie "import java.util.logging.Handler;" (co jest abstrakcyjne) zmień go na 'import android.os.Handler; ' – chacham15

8

IntentService będzie utworzyć wątku do obsługi nowego zamiarów, a zakończono ją natychmiast, gdy zadanie zostało wykonane. Więc toast będzie poza kontrolą przez martwą nić.

Powinieneś zobaczyć kilka wyjątków w konsoli, kiedy toast pokazuje się na ekranie.

+0

+1 za wskazanie mechanizmu wątku roboczego w IntentService. –

0

Aby wyświetlić toast, gdy użytkownik znajduje się w jednym z działań związanych z aplikacją.

Wystarczy odniesienie bieżącej działalności, i nazwać ten przykładowy kod:

public void showToast(final String msg) { 
    final Activity a = currentActivity; 
    if (a != null) { 
     a.runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       Toast.makeText(a, msg, Toast.LENGTH_SHORT).show(); 
      } 
     }); 
    } 
} 

Istnieje wiele opcji, aby uzyskać bieżącej działalności, sprawdź to pytanie: How to get current foreground activity context in android?

ale używam tego podejścia:

aplikacja musi posiadać:

private Activity currentActivity = null; 

public Activity getCurrentActivity() { 
    return currentActivity; 
} 

public void setCurrentActivity(Activity mCurrentActivity) { 
    this.currentActivity = mCurrentActivity; 
} 

Każde działanie musi posiadać:

@Override 
protected void onResume() { 
    super.onResume(); 
    ((MyApplication) getApplication()).setCurrentActivity(this); 

} 
@Override 
protected void onPause() { 
    super.onPause(); 
    ((MyApplication) getApplication()).setCurrentActivity(null); 
} 
+1

Wywołanie 'super.onPause()' from 'onPause' – TWiStErRob

+0

O mój boże, błąd! ... Ale już go nie ma. –

17

Działa to dla mnie:

public void ShowToastInIntentService(final String sText) { 
    final Context MyContext = this; 

    new Handler(Looper.getMainLooper()).post(new Runnable() { 
     @Override 
     public void run() { 
      Toast toast1 = Toast.makeText(MyContext, sText, Toast.LENGTH_LONG); 
      toast1.show(); 
     } 
    }); 
}; 
+0

nie działa dla mnie .. – Shmuel

+0

To mi się udało dla mnie ... Thx Ton – Vishnu

1

Dla osób rozwijających się w Xamarin studio, to jak jej zrobić tam:

Handler handler = new Handler(); 
handler.Post (() => { 
    Toast.MakeText (_Context, "Your text here.", ToastLength.Short).Show(); 
});