Tengo estas dos clases. Mi actividad principal y la que extiende el AsyncTask
, ahora en mi actividad principal necesito obtener el resultado de OnPostExecute()
la AsyncTask
. ¿Cómo puedo pasar u obtener el resultado en mi Actividad principal?
Aquí están los códigos de muestra.
Mi actividad principal
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
Esta es la clase AsyncTask
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
android
android-asynctask
Stella
fuente
fuente
Respuestas:
Fácil:
Crear
interface
clase, dondeString output
es opcional, o puede ser cualquier variable que desee devolver.Vaya a su
AsyncTask
clase y declare la interfazAsyncResponse
como un campo:En su actividad principal, necesita
implements
interactuarAsyncResponse
.ACTUALIZAR
No sabía que este es un favorito para muchos de ustedes. Así que aquí está la forma simple y conveniente de usar
interface
.sigo usando lo mismo
interface
. Para su información, puede combinar esto enAsyncTask
clase.en
AsyncTask
clase:haz esto en tu
Activity
claseO, implementando la interfaz en la Actividad nuevamente
Como puede ver 2 soluciones anteriores, la primera y la tercera, necesita crear un método
processFinish
, la otra, el método está dentro del parámetro del llamador. El tercero es más ordenado porque no hay una clase anónima anidada. Espero que esto ayudeConsejo : Cambie
String output
,String response
yString result
a diferentes tipos de coincidencia para obtener diferentes objetos.fuente
Hay algunas opciones:
Anida la
AsyncTask
clase dentro de tuActivity
clase. Suponiendo que no use la misma tarea en múltiples actividades, esta es la forma más fácil. Todo su código permanece igual, solo mueve la clase de tarea existente para que sea una clase anidada dentro de la clase de su actividad.Crea un constructor personalizado para tu
AsyncTask
que tome una referencia a tuActivity
. Instanciarías la tarea con algo asínew MyAsyncTask(this).execute(param1, param2)
.fuente
static
? Solo use cualquierafieldOrMethod
deMyActivity
oMyActivity.this.fieldOrMethod
si está sombreado.MyAsyncTask
que no es una clase interna.private
/protected
para las clases de nivel superior no está permitido, por lo tanto, pensé que debe ser unastatic
clase no interna.Sentí que el siguiente enfoque es muy fácil.
He declarado una interfaz para devolución de llamada
Luego creó una tarea asincrónica para responder a todo tipo de solicitudes paralelas
Luego llamó a la tarea asincrónica al hacer clic en un botón en la clase de actividad.
Gracias
fuente
Puedes probar este código en tu clase Main. Eso funcionó para mí, pero he implementado métodos de otra manera
fuente
execute()
, mira mi respuesta, he agregado un comentario allí. es posible que desee verificar mi respuesta actualizada. espero que esto ayude.Esta respuesta puede llegar tarde, pero me gustaría mencionar algunas cosas cuando
Activity
depende de ustedAsyncTask
. Eso lo ayudaría a evitar bloqueos y administrar la memoria. Como ya se mencionó en las respuestas anterioresinterface
, también les decimos devoluciones de llamada. Trabajarán como informadores, pero nunca enviarán referencias fuertesActivity
ointerface
siempre usarán débiles. referencias en esos casos.Consulte la captura de pantalla a continuación para descubrir cómo eso puede causar problemas.
Como puede ver si comenzamos
AsyncTask
con una referencia sólida, entonces no hay garantía de que nuestroActivity
/Fragment
estará vivo hasta que obtengamos datos, por lo que sería mejor usarloWeakReference
en esos casos y eso también ayudará en la administración de la memoria, ya que nunca lo mantendremos la fuerte referencia de nuestroActivity
entonces será elegible para la recolección de basura después de su distorsión.Consulte el fragmento de código a continuación para descubrir cómo usar la increíble WeakReference:
MyTaskInformer.java
Interfaz que funcionará como informador.MySmallAsyncTask.java
AsyncTask para hacer una tarea de larga duración, que utilizaráWeakReference
.MainActivity.java
Esta clase se usa para iniciar miAsyncTask
implementacióninterface
en esta clase yoverride
este método obligatorio.fuente
en tu Oncreate ():
``
} `
fuente
Puede hacerlo en unas pocas líneas, simplemente anule onPostExecute cuando llame a su AsyncTask. Aquí hay un ejemplo para ti:
Espero que te haya ayudado, feliz codificación :)
fuente
onPostExecute
método.¿Por qué la gente lo hace tan difícil?
Esto debería ser suficiente.
No implemente onPostExecute en la tarea asíncrona, más bien impleméntelo en la Actividad:
fuente
@Override
?Puede llamar al
get()
método deAsyncTask
(o al sobrecargadoget(long, TimeUnit)
). Este método se bloqueará hasta queAsyncTask
haya completado su trabajo, en cuyo punto le devolverá elResult
.Sería aconsejable realizar otro trabajo entre la creación / inicio de su tarea asincrónica y llamar al
get
método, de lo contrario no está utilizando la tarea asincrónica de manera muy eficiente.fuente
Puedes escribir tu propio oyente. Es lo mismo que HelmiB la respuesta de pero parece más natural:
Crear interfaz de escucha:
Luego escribe tu tarea asincrónica:
Finalmente implementar oyente en actividad:
Y así es como puede llamar a asyncTask:
fuente
Hola, puedes hacer algo como esto:
Crear clase que implementa AsyncTask
Agregar actividad principal
fuente
Cree un miembro estático en su clase de actividad. Luego asigne el valor durante el
onPostExecute
Por ejemplo, si el resultado de su AsyncTask es una Cadena, cree una cadena estática pública en su Actividad
public static String dataFromAsyncTask;
Luego, en
onPostExecute
AsyncTask, simplemente haga una llamada estática a su clase principal y establezca el valor.MainActivity.dataFromAsyncTask = "result blah";
fuente
Lo hago funcionar mediante subprocesos y manejador / mensaje. Pasos de la siguiente manera: Declarar un diálogo de progreso
Cree una función para cerrar el diálogo cuando finalice la operación.
Codifique los detalles de su ejecución:
fuente
Debe usar "protocolos" para delegar o proporcionar datos al
AsynTask
.Delegados y fuentes de datos
Un delegado es un objeto que actúa en nombre o en coordinación con otro objeto cuando ese objeto encuentra un evento en un programa. ( Definición de Apple )
Los protocolos son interfaces que definen algunos métodos para delegar algunos comportamientos.
Aquí hay un ejemplo completo !!!
fuente
prueba esto:
Y ejemplo de uso:
fuente
Probablemente exagere un poco, pero proporcioné devoluciones de llamadas tanto para el código de ejecución como para los resultados. obviamente, para la seguridad del subproceso, debe tener cuidado con lo que accede en la devolución de llamada de ejecución.
La implementación de AsyncTask:
Una devolución de llamada:
Y finalmente la ejecución de la tarea asíncrona:
fuente
Espero que hayas pasado por esto , si no, por favor lee.
https://developer.android.com/reference/android/os/AsyncTask
Dependiendo de la naturaleza de los datos de resultados, debe elegir la mejor opción posible que se le ocurra.
Es una gran opción usar una interfaz
algunas otras opciones serían ...
Si la clase AsyncTask se define dentro de la clase en la que desea utilizar el resultado. Utilice una variable global estática o get () , úsela desde la clase externa ( variable volátil si es necesario). pero debe tener en cuenta el progreso de AsyncTask o al menos asegurarse de que haya terminado la tarea y el resultado esté disponible a través del método global variable / get (). puede usar sondeo, onProgressUpdate (Progress ...) , sincronización o interfaces (lo que mejor le convenga)
Si el resultado es compatible para ser una entrada de referencia compartida o está bien que se guarde como un archivo en la memoria, puede guardarlo incluso desde la tarea en segundo plano y podría usar el método onPostExecute ()
para recibir una notificación cuando el resultado esté disponible en la memoria.
Si la cadena es lo suficientemente pequeña y se debe utilizar al inicio de una actividad es posible usar intentos ( putExtra () ) dentro de onPostExecute () , pero recuerde que los contextos estáticos no son tan seguros de manejar.
Si es posible, puede llamar a un método estático desde el método onPostExecute (), siendo el resultado su parámetro
fuente