Cómo obtener el resultado de OnPostExecute () en la actividad principal porque AsyncTask es una clase aparte?

Tengo estas dos clases. Mi actividad principal y la que extiende el AsyncTask , ahora en mi actividad principal necesito obtener el resultado de OnPostExecute() en AsyncTask . ¿Cómo puedo pasar o obtener el resultado a mi actividad principal?

Aquí están los códigos de ejemplo.

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

Fácil:

  1. Crear clase de interface , donde String output es opcional, o puede ser cualquier variable que quiera devolver.

     public interface AsyncResponse { void processFinish(String output); } 
  2. Vaya a su clase AsyncTask y declare la interfaz AsyncResponse como un campo:

     public class MyAsyncTask extends AsyncTask{ public AsyncResponse delegate = null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); } } 
  3. En su actividad principal necesita implements interfaz AsyncResponse .

     public class MainActivity implements AsyncResponse{ MyAsyncTask asyncTask =new MyAsyncTask(); @Override public void onCreate(Bundle savedInstanceState) { //this to set delegate/listener back to this class asyncTask.delegate = this; //execute the async task asyncTask.execute(); } //this override the implemented method from asyncTask @Override void processFinish(String output){ //Here you will receive the result fired from async class //of onPostExecute(result) method. } } 

ACTUALIZAR

No sabía que este es un favorito para muchos de ustedes. Así que aquí está la manera simple y conveniente de usar la interface .

Aún utilizando la misma interface . FYI, puede combinar esto en la clase AsyncTask .

En la clase AsyncTask :

 public class MyAsyncTask extends AsyncTask{ // you may separate this or combined to caller class. public interface AsyncResponse { void processFinish(String output); } public AsyncResponse delegate = null; public MyAsyncTask(AsyncResponse delegate){ this.delegate = delegate; } @Override protected void onPostExecute(String result) { delegate.processFinish(result); } } 

Haz esto en tu clase de Activity

 public class MainActivity extends Activity { MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse(){ @Override void processFinish(String output){ //Here you will receive the result fired from async class //of onPostExecute(result) method. } }).execute(); } 

O, la implementación de la interfaz en la actividad de nuevo

 public class MainActivity extends Activity implements AsyncResponse{ @Override public void onCreate(Bundle savedInstanceState) { //execute the async task new MyAsyncTask(this).execute(); } //this override the implemented method from AsyncResponse @Override void processFinish(String output){ //Here you will receive the result fired from async class //of onPostExecute(result) method. } } 

Como se puede ver 2 soluciones anteriores, el primero y el tercero, que necesita para crear el método de processFinish , el otro, el método está dentro del parámetro llamador. La tercera es más ordenada porque no hay clase anidada anidada. Espero que esto ayude

Hay algunas opciones:

  • AsyncTask clase AsyncTask dentro de su clase de Activity . Suponiendo que no utilice la misma tarea en múltiples actividades, esta es la forma más fácil. Todo su código permanece igual, basta con mover la clase de tarea existente para que sea una clase anidada dentro de la clase de su actividad.

     public class MyActivity extends Activity { // existing Activity code ... private class MyAsyncTask extends AsyncTask<String, Void, String> { // existing AsyncTask code ... } } 
  • Cree un constructor personalizado para su AsyncTask que tome una referencia a su Activity . Se podría instanciar la tarea con algo como new MyAsyncTask(this).execute(param1, param2) .

     public class MyAsyncTask extends AsyncTask<String, Void, String> { private Activity activity; public MyAsyncTask(Activity activity) { this.activity = activity; } // existing AsyncTask code ... } 

Me sentí el enfoque de abajo es muy fácil.

He declarado una interfaz para la devolución de llamada

 public interface AsyncResponse { void processFinish(Object output); } 

A continuación, se creó tarea asíncrona para responder a todo tipo de solicitudes paralelas

  public class MyAsyncTask extends AsyncTask<Object, Object, Object> { public AsyncResponse delegate = null;//Call back interface public MyAsyncTask(AsyncResponse asyncResponse) { delegate = asyncResponse;//Assigning call back interfacethrough constructor } @Override protected Object doInBackground(Object... params) { //My Background tasks are written here return {resutl Object} } @Override protected void onPostExecute(Object result) { delegate.processFinish(result); } } 

A continuación, se llama la tarea asincrónica al hacer clic en un botón de la clase de actividad.

 public class MainActivity extends Activity{ @Override public void onCreate(Bundle savedInstanceState) { Button mbtnPress = (Button) findViewById(R.id.btnPress); mbtnPress.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() { @Override public void processFinish(Object output) { Log.d("Response From Asynchronous task:", (String) output); mbtnPress.setText((String) output); } }); asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." }); } }); } } 

Gracias

Puede probar este código en su clase principal. Eso funcionó para mí, pero he implementado los métodos de otra manera

 try { String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get(); } catch (ExecutionException | InterruptedException ei) { ei.printStackTrace(); } 

Puede hacerlo en pocas líneas, simplemente anule onPostExecute cuando llame a su AsyncTask. He aquí un ejemplo para ti:

 new AasyncTask() { @Override public void onPostExecute(String result) { // do whatever you want with result } }.execute(a.targetServer); 

Espero que te haya ayudado, feliz codding 🙂

En su Oncreate ():

 myTask.execute("url"); String result = ""; try { result = myTask.get().toString(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); 

Todos los derechos reservados

Hola puedes hacer algo como esto:

  1. Crear clase que implementa AsyncTask

     // TASK public class SomeClass extends AsyncTask<Void, Void, String>> { private OnTaskExecutionFinished _task_finished_event; public interface OnTaskExecutionFinished { public void OnTaskFihishedEvent(String Reslut); } public void setOnTaskFinishedEvent(OnTaskExecutionFinished _event) { if(_event != null) { this._task_finished_event = _event; } } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(Void... params) { // do your background task here ... return "Done!"; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if(this._task_finished_event != null) { this._task_finished_event.OnTaskFihishedEvent(result); } else { Log.d("SomeClass", "task_finished even is null"); } } } 
  2. Añadir en la actividad principal

     // MAIN ACTIVITY public class MyActivity extends ListActivity { ... SomeClass _some_class = new SomeClass(); _someclass.setOnTaskFinishedEvent(new _some_class.OnTaskExecutionFinished() { @Override public void OnTaskFihishedEvent(String result) { Toast.makeText(getApplicationContext(), "Phony thread finished: " + result, Toast.LENGTH_SHORT).show(); } }); _some_class.execute(); ... } 

Puedes escribir tu propio oyente. Es lo mismo que la respuesta de HelmiB , pero parece más natural:

Crear interfaz de escucha:

 public interface myAsyncTaskCompletedListener { void onMyAsynTaskCompleted(int responseCode, String result); } 

A continuación, escriba su tarea asíncrona:

 public class myAsyncTask extends AsyncTask<String, Void, String> { private myAsyncTaskCompletedListener listener; private int responseCode = 0; public myAsyncTask() { } public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) { this.listener = listener; this.responseCode = responseCode; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { String result; String param = (params.length == 0) ? null : params[0]; if (param != null) { // Do some background jobs, like httprequest... return result; } return null; } @Override protected void onPostExecute(String finalResult) { super.onPostExecute(finalResult); if (!isCancelled()) { if (listener != null) { listener.onMyAsynTaskCompleted(responseCode, finalResult); } } } } 

Finalmente, implemente el listener en la actividad:

 public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener { @Override public void onMyAsynTaskCompleted(int responseCode, String result) { switch (responseCode) { case TASK_CODE_ONE: // Do something for CODE_ONE break; case TASK_CODE_TWO: // Do something for CODE_TWO break; default: // Show some error code } } 

Y así es como puedes llamar a asyncTask:

  protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Some other codes... new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job"); // And some another codes... } 

Cree un miembro estático en su clase de actividad. A continuación, asigne el valor durante el proceso 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;

A continuación, en el onPostExecute de AsyncTask, simplemente haga una llamada estática a su clase principal y establezca el valor.

MainActivity.dataFromAsyncTask = "result blah";

Puede llamar al método get() de AsyncTask (o al overloaded get(long, TimeUnit) ). Este método se bloqueará hasta que el AsyncTask haya completado su trabajo, momento en el cual le devolverá el Result .

Hago que funcione usando threading y handler / mensaje. Pasos a seguir: Declare un diálogo de progreso

 ProgressDialog loadingdialog; 

Cree una función para cerrar el cuadro de diálogo cuando finalice la operación.

  private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { loadingdialog.dismiss(); } }; 

Codifique sus detalles de ejecución:

  public void startUpload(String filepath) { loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true); final String _path = filepath; new Thread() { public void run() { try { UploadFile(_path, getHostName(), getPortNo()); handler.sendEmptyMessage(0); } catch (Exception e) { Log.e("threadmessage", e.getMessage()); } } }.start(); } 

¿Por qué la gente lo hace tan difícil.

Esto debería ser suficiente.

No implemente onPostExecute en la tarea async, sino que la implementa en la Activity:

 public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { //execute the async task MyAsyncTask task = new MyAsyncTask(){ protected void onPostExecute(String result) { //Do your thing } } task.execute("Param"); } } 

Esta respuesta podría ser tarde, pero me gustaría mencionar algunas cosas cuando su Activity depende de AsyncTask . Eso le ayudaría a evitar accidentes y gestión de memoria. Como ya se mencionó en las respuestas anteriores van con interface , también les decimos callbacks. Trabajarán como informante, pero nunca envíen referencia fuerte de Activity o interface siempre usan referencia débil en esos casos.

Consulte la siguiente captura de pantalla para averiguar cómo puede causar problemas.

Introduzca aquí la descripción de la imagen

Como puedes ver si empezamos AsyncTask con una referencia fuerte, entonces no hay garantía de que nuestra Activity / Fragment estará viva hasta que obtengamos datos, así que sería mejor usar WeakReference en esos casos y eso también ayudará en la administración de memoria como Nunca mantendremos la referencia fuerte de nuestra Activity entonces será elegible para recolección de basura después de su distorsión.

Compruebe debajo del fragmento de código para saber cómo usar WeakReference impresionante –

MyTaskInformer.java Interfaz que funcionará como un informante.

 public interface MyTaskInformer { void onTaskDone(String output); } 

MySmallAsyncTask.java AsyncTask para realizar una tarea de ejecución larga, que utilizará WeakReference .

 public class MySmallAsyncTask extends AsyncTask<String, Void, String> { // ***** Hold weak reference ***** private WeakReference<MyTaskInformer> mCallBack; public MySmallAsyncTask(MyTaskInformer callback) { this.mCallBack = new WeakReference<>(callback); } @Override protected String doInBackground(String... params) { // Here do whatever your task is like reading/writing file // or read data from your server or any other heavy task // Let us suppose here you get response, just return it final String output = "Any out, mine is just demo output"; // Return it from here to post execute return output; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); // Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask // Make sure your caller is active final MyTaskInformer callBack = mCallBack.get(); if(callBack != null) { callBack.onTaskDone(s); } } } 

MainActivity.java Esta clase se utiliza para iniciar mi interface implementación AsyncTask en esta clase y override este método obligatorio.

 public class MainActivity extends Activity implements MyTaskInformer { private TextView mMyTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMyTextView = (TextView) findViewById(R.id.tv_text_view); // Start your AsyncTask and pass reference of MyTaskInformer in constructor new MySmallAsyncTask(this).execute(); } @Override public void onTaskDone(String output) { // Here you will receive output only if your Activity is alive. // no need to add checks like if(!isFinishing()) mMyTextView.setText(output); } } 
  • Tarea asíncrona que toma demasiado tiempo para hacer el trabajo
  • Android AsyncTask no llamando a onPostExecute
  • Clase de BlackBerry equivalente a AsyncTask?
  • Android AsyncTasks Cómo comprobar si la actividad aún se está ejecutando
  • ¿Cómo ejecutar una tarea asíncrona para cada x min en android?
  • Necesito saber cuánto bytes se ha cargado para actualizar una barra de progreso android
  • ¿Cuándo usar un Servicio o AsyncTask o Handler?
  • Cómo realizar operaciones de base de datos mediante Async Task
  • Cancelar AsyncTask después de algún tiempo
  • Espere a que se complete el AsyncTask múltiple
  • Descargar imágenes con AsyncTask
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.