Domanda

Ho un'attività chiamato A, e sulla selezione della voce del menu 0, avvia servizio B, che avvia un C eseguibile in un nuovo filo. Ho un TextView nell'attività A, che voglio accedere in discussione C.

Ho provato a fare il TextView un campo statico pubblico, ma che genera il seguente errore:

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)

Ho anche considerato cercando di passare il Vista attraverso un intento, ma non so come dovrebbe funzionare. Di cosa ho bisogno per fare questo lavoro?

È stato utile?

Soluzione

È necessario aggiornare i widget dal thread GUI, alias 'thread che ha creato la gerarchia vista'. Il metodo standard per farlo è tramite Handler s ed un esempio di come utilizzare gestori possono essere trovati nella ProgressDialog Esempio ( ampliare 'Esempio ProgressDialog con un secondo filo').

Altri suggerimenti

ho avuto un problema simile in cui è stato richiesto un controllo ListView per essere aggiornato sulla risposta servizio web proveniente da un thread separato.

Dopo aver analizzato un simile domanda e esempio , ecco una soluzione che dovrebbe funzionare per voi:

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

È davvero non si vuole essere direttamente manipolare i widget da un servizio.

Ad esempio, supponiamo che l'utente fa scorrere la tastiera del suo G1. La vostra attività è distrutto e ricreato. Il vostro servizio, tuttavia, è tenuta su widget da un'attività ormai defunta. Nella migliore delle ipotesi, non si verificano gli aggiornamenti. Nel peggiore dei casi, gli aggiornamenti verranno causare un crash, o l'applicazione perderà la memoria perché la vecchia attività non può essere garbage collection, perché il servizio detiene ancora su di esso.

Avere servizi notificare attività va bene, fino a quando si dispone di isolamento decente tra di loro e l'attività si stacca dal servizio quando viene distrutta.

L'altro modo è quello di utilizzare os.android.AsyncTask per l'elaborazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top