2012-12-06 13 views
18

Witam Chcę, aby Toast był dla mnie dostępny bez względu na wszystko i dostępny z dowolnego wątku, kiedy tylko zechcę w mojej aplikacji. Więc to zrobić ja przedłużony klasę Activity:android - wywoływanie wątku interfejsu użytkownika z wątku roboczego

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.widget.Toast; 

public class MyActivity extends Activity{ 
    private Handler mHandler; 

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

    private class ToastRunnable implements Runnable { 
     String mText; 

     public ToastRunnable(String text) { 
      mText = text; 
     } 

     public void run(){ 
      Toast.makeText(getApplicationContext(), mText, Toast.LENGTH_SHORT).show(); 
     } 
    } 

    public void doToast(String msg) { 
     mHandler.post(new ToastRunnable(msg)); 
    } 
} 

tak aby wszystkieActivity zajęcia w mojej aplikacji są teraz po prostu

public class AppMain extends MyActivity { 
    //blah 
} 

czego się spodziewałem, aby móc to zrobić (w wątku roboczego) było to:

try{ 
    MyActivity me = (MyActivity) Looper.getMainLooper().getThread(); 
    me.doToast("Hello World"); 
} 
catch (Exception ex){ 
    Log.e("oh dear", ex.getMessage()); 
} 

i tak długo, jak Activity był „MyActivity” to powinno działać - ale problem polega na tym, że --- Looper.getMainLooper().getThread(); nie zwraca mi wartości MyActivity i to powoduje, że płaczę - co robię źle?

: EDIT:

niektóre tła wyjaśnić "dlaczego" Siedzę z tego typu implmentation.

Muszę być w stanie potwierdzić użytkownikowi, że zdarzenie "POST HTTP" zakończyło się sukcesem. Teraz. Jeśli użytkownik kliknie "OK" na formularzu UI MAY lub NIE MA MAI Internetu w tym czasie .. Jeśli ma Internet - wszystko dobrze i dobrze - to wysyła formularz przez HTTP POST wszystko dobrze i dobrze .. ale jeśli istnieje NO Internet większość (99,999% z Android lame/żałosne/mewling na to, a przede wszystkim zaoferować użytkownikowi nie plan „b” zakładając, że w każdej chwili internet jest tam - gdy nie jest)

Moja aplikacja nie "pójdzie źle (jak ja to nazywam)" - ma plan "b" zamiast tego "Kolejkuje" zdarzenie postu i ponawia próbę co x minut .. teraz jest to cichy wątek w Tło .. Mam dużo interakcji użytkownika w całej aplikacji, nie wiem, gdzie użytkownik będzie "być", ale w końcu, gdy HTTP POST, kolejka/ponowna próba/kolejka/ponowienie, zwróci "! Powodzenie! "Chcę Toast że jako wiadomość do użytkownika (np:«Twój formularz został wysłany»)

Odpowiedz

50

Co z runOnUiThread

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

activity.runOnUiThread(new Runnable() { 
    public void run() { 
     Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show(); 
    } 
}); 
+0

Nie, chcę odpowiedzieć 'wiadomości Toast' dla użytkownika,' runOnUiThread' akceptuje 'Runnable action który' Toast' nie działa z – conners

+0

nie ma 'activity' ponieważ nie ma' kontekst ' – conners

+1

Dlaczego nie użyć' getApplicationContext() '? – Rawkode

6

użytku poniższym kodzie utworzyć aktywność?. obiekt, który zawiera instancję aktywności ..

activity.runOnUiThread(new Runnable() { 
    public void run() { 
    Toast.makeText(activity.getApplicationContext(),"Toast text",Toast.LENGTH_SHORT).show(); 
    } 
); 
+0

Jestem w wątku 'worker', w którym nie ma' aktywności '(nie można go przeżyć jako parametr, ponieważ pracownik nieustannie próbuje połączyć się z serwerem, aby wysłać wiadomość. Aktywność wywołuje, a następnie zamyka się. Muszę potwierdzić z serwera i potwierdzić zdarzenie użytkownikowi, gdy tylko się to stanie. potrzebujemy systemu Android, aby wykrztusił bieżący wątek interfejsu użytkownika jako działanie: – conners

+0

Jeśli nie możesz przekazać odwołania do wątku roboczego do wątku roboczego, to oczywiste jest, że Projekt reklamy jest źródłem problemu. Powinieneś być w stanie przekazać referencję podczas tworzenia nici, zamiast sugerować, że wątek zmaterializował się sam. – LoungeKatt

2

nie można po prostu rzucać wynikiem getThread() do instanc e twojej klasy bazowej MyActivity. getThread() zwraca wartość Thread, która nie ma nic wspólnego z Activity.

Nie ma wielkiego - czytaj: czysty - sposób robienia tego, co chcesz robić. W pewnym momencie abstrakcja "wątku roboczego" będzie musiała mieć odniesienie do czegoś, co może stworzyć dla ciebie Toast. Zapisanie pewnej statycznej zmiennej zawierającej odniesienie do twojej podklasy Activity po prostu by móc skrócić tworzenie Toast jest receptą na wycieki pamięci i ból.

+0

Nie używam klasy statycznej, jest to podstawowe rozszerzenie do 'Aktywności', które obejmuje' Handler'. Wszystko, co chcę, żeby Android usunął bieżącą czynność. – conners

+1

@conners: To nie zmienia faktu, że ' getThread() 'zwraca' Wątek', który nie jest 'Aktywnością', nie mówiąc o' MyActivity'. – CommonsWare

+0

Zgadzam się, ale musi istnieć sposób, w zakresie, w jakim Android pozwala mi w SDK "Activity" jest przednią stroną wątku UI .. Nie jestem pewien, dlaczego nie ma 'Looper.getMainLooper() .getThread(). getActivity()/.getContext() 'szczerze mówiąc .. Spodziewałem się, że będzie jeden. większość rozwiązań wymaga podania kontekstu jako parametru - ale co, jeśli nie wiesz, jaki jest kontekst lub co, jeśli jest to zdarzenie zamykające formularz, które wywołało pracownika (jak w moim przypadku)? – conners

0

Jeśli jest to w ramach własnej działalności, dlaczego nie można po prostu zadzwonić pod numer doToast()?

1

Dlaczego nie wysyłasz intencji przechwytywanej przez BroadCastReceiver, wtedy odbiornik transmisji może utworzyć powiadomienie na pasku powiadomień. To nie jest toast, ale jest sposobem poinformowania użytkownika, że ​​jego wpis zakończył się sukcesem.

4

Pozwoli to wyświetlić komunikat bez konieczności polegania na kontekście, aby uruchomić toast, tylko po to, aby odwoływać się przy wyświetlaniu samej wiadomości.

runOnUiThread nie działał z wątku OpenGL View i to było rozwiązanie. Mam nadzieję, że to pomoże.

private Handler handler = new Handler(); 
handler.post(new Runnable() { 
    public void run() { 
     Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show(); 
    } 
}); 
1

Jeśli masz kontekst z tobą, możesz wywołać taki wątek z klasy niezwiązanej z działaniem.

((Activity)context).runOnUiThread(new Runnable() { 
    public void run() { 
     // things need to work on ui thread 
    } 
}); 
Powiązane problemy