2009-07-21 5 views
29

Mam działanie o nazwie A, a po wybraniu pozycji menu 0 uruchamia usługę B, która uruchamia działającą literę C w nowym wątku. Mam TextView aktywności A, którego chcę, aby uzyskać dostęp w wątku CJak uzyskać dostęp do widoków oryginalnego działania z usługi utworzonego tła

Próbowałem uczynienie TextView pola statycznego publicznego, ale to generuje następujący błąd:

07-21 07:26:25.723: ERROR/AndroidRuntime(1975): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewRoot.checkThread(ViewRoot.java:2440) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewRoot.invalidateChild(ViewRoot.java:522) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:540) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.ViewGroup.invalidateChild(ViewGroup.java:2332) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.view.View.invalidate(View.java:4437) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.updateAfterEdit(TextView.java:4593) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.handleTextChanged(TextView.java:5932) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:6081) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.sendTextChange(SpannableStringBuilder.java:889) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:352) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:269) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:432) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:259) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:28) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.append(TextView.java:2191) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at android.widget.TextView.append(TextView.java:2178) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at com.android.peekaboo.DoScan$scanBody.run(DoScan.java:36) 
07-21 07:26:25.723: ERROR/AndroidRuntime(1975):  at java.lang.Thread.run(Thread.java:1058) 

Mam też za przemyślane próby przekazania Widoku przez intencję, ale nie wiem, jak to by działało. Co muszę zrobić, aby to zadziałało?

Odpowiedz

21

Musisz zaktualizować widżety z wątku GUI, inaczej "wątek, który utworzył hierarchię widoków". Standardowy sposób wykonania tej czynności to: Handler s. Przykład użycia instrukcji obsługi można znaleźć w ProgressDialog Example (rozwinąć "Example ProgressDialog z drugim wątkiem").

1

Innym sposobem jest wykorzystanie do przetwarzania przetwarzania os.android.AsyncTask.

2

Naprawdę nie chcesz bezpośrednio manipulować widżetami z usługi.

Załóżmy na przykład, że użytkownik wysuwa klawiaturę swojego G1. Twoja aktywność jest niszczona i odtwarzana. Twoja usługa trzyma jednak widżety z nieistniejącej już działalności. W najlepszym razie aktualizacje się nie pojawią. W najgorszym przypadku aktualizacje spowodują awarię lub Twoja aplikacja spowoduje wyciek pamięci, ponieważ stara aktywność nie może zostać usunięta, ponieważ usługa nadal jest na niej przechowywana.

Posiadanie usług powiadamiania o czynnościach jest OK, o ile posiadasz przyzwoitą izolację między nimi, a działanie odłącza się od usługi po jej zniszczeniu.

25

Wystąpił podobny problem, w którym ListView wymagał aktualizacji w odpowiedzi na usługę sieciową pochodzącej z oddzielnego wątku.

Po przeanalizowaniu similar question & example, tutaj jest to rozwiązanie, które powinny pracować dla Ciebie:

public class A extends Activity implements Callback { 

    callserviceB() { } // where your service B being called; 

    @Override 
    public void returnServiceResponse() { 
      workOnResponse(); 
      handler.sendEmptyMessage(0); 
    } 

    private Handler handler = new Handler() { 
      public void handleMessage(Message msg) { 
       //update your view from here only. 
      } 
    } 
} 

public class B implements Runnable { 
    Callback callback; 

    public void run() { 
     //your business logic. 
     callback.returnServiceResponse(); 
    } 
} 

public interface Callback { 
    public void returnServiceResponse(); 
} 
+2

przykłady kodu są zawsze o wiele bardziej przydatne niż opisów. Dzięki :) – HXCaine

+0

Dziękuję, ten problem śledził mnie przez długi czas! Dziękuję Ci! – Daniel

Powiązane problemy