Frage

Ich habe eine Aktivität A genannt, und bei der Auswahl des Menüpunktes 0, es laicht Service B, die ein lauffähiges C in einem neuen Thread startet. Ich habe eine Textview in Aktivität A, die ich in dem Thread C zugreifen möchten

Ich habe versucht, das Textview ein öffentliches statisches Feld zu machen, aber das erzeugt die folgenden Fehler:

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)

Ich habe auch versucht, betrachten die Ansicht durch eine Absicht passieren, aber nicht wissen, wie das funktionieren würde. Was muss ich diese Arbeit machen?

War es hilfreich?

Lösung

Sie haben Widgets aus dem GUI-Thread zu aktualisieren, auch bekannt als ‚den Thread, der die Ansichtshierarchie erstellt.‘ Der üblicher Weg, dies zu tun ist über Handler s und ein Beispiel für wie Sie können Handler in der ProgressDialog Beispiel gefunden werden ( erweitern 'Beispiel ProgressDialog mit einem zweiten Gewinde').

Andere Tipps

Ich habe ein ähnliches Problem, bei dem ein Listview erforderlich war, auf der Web-Service-Antwort von einem separaten Thread kommenden aktualisiert werden.

Nach einem ähnliche Frage & Beispiel , hier ist eine Lösung, die für Sie arbeiten soll:

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();
}

Sie wollen wirklich nicht direkt sein Widgets von einem Dienst zu manipulieren.

Angenommen, schiebt der Benutzer die Tastatur ihres G1 aus. Ihre Aktivität wird zerstört und neu erstellt. Ihr Service jedoch hält an Widgets aus einer heute nicht mehr existierenden Aktivität. Im besten Fall wird nicht auftreten, das Updates. Im schlimmsten Fall führt dazu, dass der Updates einen Absturz oder Ihre Anwendung wird ein Speicherleck auf, weil die alte Tätigkeit nicht Garbage Collection sein kann, weil Sie da noch auf sie hält.

Mit Dienstleistungen Aktivitäten benachrichtigen ist in Ordnung, solange Sie anständige Trennung zwischen ihnen und die Aktivität löst sich vom Dienst, wenn es zerstört wird.

Der andere Weg ist os.android.AsyncTask für die Verarbeitung zu nutzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top