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:
- Android: cómo asegurarse de que un AsyncTask se termina antes de llamar a otro método?
- Cómo gestionar varias tareas asíncronas de forma eficiente en Android
- AsyncTask - ¿qué parámetros se necesitan para extender y doInBackground?
- De error de memoria durante el uso de viewpager + imageview incluso cuando se utiliza la memoria caché y asynctask
- Cómo hacer una pantalla de bien codificada de bienvenida
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.
- ListView es muy lento - android
- Cómo utilizar AsyncTask en Servicios en Android?
- Android: Process.myTid () VS Thread.currentThread (). GetId ()
- ¿Cómo dar una barra de progreso para la descarga?
- Rellenar ListView en fragmento después de Async hecho de la actividad
- Cancelar AsyncTask después de algún tiempo
- ¿AsyncTask sigue esperando?
- Buscando un buen ejemplo de usar get () con un AsyncTask en android
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 surunOnUiThread(Runnable)
- Dependiendo de la modificación utilice uno de los métodos de la
post...()
deView
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)
- Android consigue el ancho completo para el cuadro de diálogo personalizado
- SharedPreferences putStringSet no funciona