AsyncTask "Sólo el subproceso original que creó una jerarquía de vista puede tocar sus vistas."

Intento modificar el contenido de Spinner a través del AsyncTaks pero no puedo y el Logcat se escribe "09-19 16: 36: 11.189: ERROR / ERROR EL (6078): Sólo el hilo original que creó una jerarquía de vista puede tocar su puntos de vista.".

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 la función setGroups 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; } } 

¿Qué está mal? Gracias.

Como se mencionó por Peter, no se puede acceder a las vistas utilizando doInBackground() . Usted puede hacer eso dentro onPostExecute() sin embargo. Que es donde se supone que trabajar con los resultados doInBackground() regreso en la medida de lo que sé.

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

Para aquellos de ustedes que están empezando a recoger el desarrollo de Android:
doInBackground() : todo lo que ocurre en otro hilo (en segundo plano) diferente del hilo principal / original en el que opera tu vista / fragmento / actividad (este es el punto completo de AsyncTask ==> no puedes tocar las vistas!
onPostExecute() : ahora se hacen cosas de fondo, aquí está de vuelta en el hilo principal / hilo ==> puedes tocar las vistas ahora!

Está intentando acceder a los componentes de la interfaz de usuario (Vista) desde un subproceso de fondo en su caso dentro del método doInBackground() . No se le permite hacer eso .

Un poco más detalles

Problema :

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

Solución :

  • Modificar las vistas en el método onPostExecute() – se ejecuta en el subproceso de interfaz de usuario
  • Obtener una referencia a una Activity y utilizar su runOnUiThread(Runnable)
  • Dependiendo de la modificación utilice uno de los métodos de la post...() de View

Si desea mostrar el progreso durante el proceso de fondo, ninguna de las respuestas anteriores da una pista: Cuando OnPostExecute se llama todo está terminado por lo que no hay necesidad de actualizar el estado de la carga.

Por lo tanto, 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 se lea por onProgressUpdate . Por ejemplo usando String:

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

En el método de fondo que llamas publishProgress(value as String) que llama automáticamente onProgressUpdate método onProgressUpdate que utiliza el subproceso de la interfaz de usuario principal:

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

Más en general, al declarar un AsyncTask debe especificar las clases <Params, Progress, Result> que se pasan a los métodos principales, éstas pueden ser sus propias clases o simplemente clases Java:

  • doInBackground(Params... params)
  • onProgressUpdate(Progress... value)
  • onPostExecute(Result... success)
  • AndroidRX - ejecuta el método en segundo plano
  • Después de ASyncTask.execute () do x () de Activity
  • Android: Cargando una imagen desde la Web con Asynctask
  • ¿Cómo puedo devolver un ArrayList de mi AsyncTask?
  • Implementar AsyncTask en Fragmento android
  • Cómo gestionar diferentes tareas que deben ser llamadas por AsyncTask
  • Android no finaliza el subproceso ASyncTask después de onPostExecution
  • El selector de intenciones permanece abierto cuando usa un subproceso para obtener un recurso de imagen
  • Entidad devuelve error en MultiPartEntityBuilder
  • Si Asynctask se está ejecutando la actividad estará vivo incluso después del método finish ()?
  • Uso de AsyncTask
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.