2011-09-19 8 views
8

Intento modificar el contenido de Spinner en AsyncTaks pero no puedo y el Logcat escribe "09-19 16: 36: 11.189: ERROR/ERROR THE (6078): Solo el hilo original que creó una jerarquía de vista puede tocar sus puntos de vista ".AsyncTask "Solo el subproceso original que creó una jerarquía de vista puede tocar sus vistas".

public class GetGroups extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected Void doInBackground(Void... params) { 
     Spinner combo = (Spinner) findViewById(R.id.group_combo); 

     setGroups(combo); 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void unused) 
    { 
     super.onPostExecute(unused); 


     Spinner combo = (Spinner) findViewById(R.id.severity_combo); 

     combo.setSelection(1); 

     //updateGroups(); 
     //if (!isFinishing()) 
     //{ 
      /*Spinner combo = (Spinner) findViewById(R.id.group_combo); 
      ProgressBar pg = (ProgressBar) findViewById(R.id.loading_group); 

      pg.setVisibility(ProgressBar.GONE); 
      combo.setVisibility(Spinner.VISIBLE); 

      combo.setSelection(0);*/ 
     //} 
    } 
} 
} 

Y los setgroups función es:

public void setGroups(Spinner combo) { 

    try { 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 

     HttpPost httpPost = new HttpPost(this.object.url); 

     List<NameValuePair> parameters = new ArrayList<NameValuePair>(2); 
     parameters.add(new BasicNameValuePair("user", this.object.user)); 
     parameters.add(new BasicNameValuePair("pass", this.object.password)); 
     parameters.add(new BasicNameValuePair("op", "get")); 
     parameters.add(new BasicNameValuePair("op2", "groups")); 
     parameters.add(new BasicNameValuePair("other_mode", "url_encode_separator_|")); 
     parameters.add(new BasicNameValuePair("return_type", "csv")); 
     parameters.add(new BasicNameValuePair("other", ";")); 

     UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters); 

     httpPost.setEntity(entity); 

     HttpResponse response = httpClient.execute(httpPost); 
     HttpEntity entityResponse = response.getEntity(); 

     String return_api = this.object.convertStreamToString(entityResponse.getContent()); 

     String[] lines = return_api.split("\n"); 

     ArrayList<String> array = new ArrayList<String>(); 

     for (int i= 0; i < lines.length; i++) { 
      String[] groups = lines[i].split(";", 21); 

      this.pandoraGroups.put(new Integer(groups[0]), groups[1]); 

      array.add(groups[1]); 
     } 

     ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_spinner_item, 
      array); 
     combo.setAdapter(spinnerArrayAdapter); 
    } 
    catch (Exception e) { 
     Log.e("ERROR THE ", e.getMessage()); 

     return; 
    } 
} 

Cuál es el problema? Gracias.

+0

es GetGroups una clase interna? –

+1

¿Qué estás tratando de hacer? – Ronnie

+0

posible duplicado de [Solo el hilo original que creó una jerarquía de vista puede tocar sus vistas] (http://stackoverflow.com/questions/10497854/only-the-original-thread-thehatcreated-a-view-hierarchy- can-touch-its-views) –

Respuesta

10

Está intentando acceder a los componentes de la interfaz de usuario (vista) desde una cadena de fondo en su caso dentro del método doInBackground(). Usted es not allowed to do that.

24

Según lo mencionado por Peter, no puede tener acceso a las vistas usando doInBackground(). Puedes hacerlo dentro de onPostExecute() sin embargo. Ahí es donde se supone que debes trabajar con los resultados doInBackground(), hasta donde yo sé.

Me encontré con este problema y lo solucioné moviendo el código de modificación de la vista al onPostExecute().

Para aquellos de ustedes que están empezando a aumentar el desarrollo de Android:
- doInBackground(): lo interior suceden en otro hilo (en el fondo) diferente del hilo principal/original de sus puntos de vista/fragmento/actividad opera en (este es el punto de AsyncTask ==> no se puede tocar los puntos de vista
- onPostExecute(): ahora telas del fondo se hacen, aquí está de vuelta en el hilo principal/hilo ==> se puede tocar los puntos de vista ahora

3

Si! Si desea mostrar el progreso durante el proceso en segundo plano, ninguna de las respuestas anteriores da una pista: cuando se llama al OnPostExecute, todo está terminado. ed así que no hay necesidad de actualizar el estado de la carga.

Por lo tanto, usted tiene que anular onProgressUpdate en su AsyncTask y asegúrese de que el segundo objeto no es un vacío, sino un entero o una cadena que es leído por onProgressUpdate.Por ejemplo, usando la secuencia:

public class MyAsyncTask extends AsyncTask<Void, String, Void> { 

    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     if (values != null && values.length > 0) { 
      //Your View attribute object in the activity 
      // already initialized in the onCreate! 
      mStatusMessageView.setText(values[0]); 
     } 
    } 
} 

que en el método de fondo se llama publishProgress(value as String) el que llama automáticamente onProgressUpdate método que use hilo principal interfaz de usuario:

@Override 
protected Boolean doInBackground(Void... params) { 
    your code... 
    publishProgress("My % status..."); 
    your code... 
    publishProgress("Done!"); 
} 

Más en general, cuando se declara un AsyncTask que tiene que especifique las clases <Params, Progress, Result> que se pasan a los métodos principales, estas pueden ser sus propias clases o solo clases Java:

  • doInBackground(Params... params)
  • onProgressUpdate(Progress... value)
  • onPostExecute(Result... success)
+0

llamé invalidar en onProgressUpdate y funciona sin ningún error. –

3

un poco más detalles

Problema:

  • elementos de interfaz de usuario pueden ser modificados en sólo el hilo de interfaz de usuario. Una excepción es su método postInvalidate() (y sus variantes) que se puede ejecutar desde fuera de UI Thread
  • el error que recibe es causado por un intento de modificar un elemento UI (un View) desde fuera del subproceso UI - doInBackground() se ejecuta en un subproceso de fondo

Solución:

  • modificar los puntos de vista en el método onPostExecute() - que se ejecuta en el hilo de interfaz de usuario
  • obtener una referencia a la una Activity y utilizar su runOnUiThread(Runnable) método
  • dependiendo del uso modificación uno de post...() métodos la View 's
Cuestiones relacionadas