studio publishprogress oncancelled example clase cancel asynctask java android multithreading android-asynctask

java - publishprogress - execute asynctask android



La clase interna puede acceder pero no actualizar valores-AsyncTask (1)

Estoy intentando descomprimir una carpeta usando AsyncTask de Android. La clase (llamada Descompresión) es una clase interna de Unzip donde Descomprimir es una clase que no es Actividad. El pseudo-código es:

public class Unzip { private String index; private String unzipDest; //destination file for storing folder. private Activity activity; private boolean result; //result of decompress. public void unzip(String loc) { Decompress workThread = new Decompress(loc, activity); workThread.execute(); if(unzip operation was successful) { display(index); } //Class Decompress: class Decompress extends AsyncTask<Void, Integer, Boolean> { private ProgressDialog pd = null; private Context mContext; private String loc; private int nEntries; private int entriesUnzipped; public Decompress(String location, Context c) { loc = location; mContext = c; nEntries = 0; entriesUnzipped = 0; Log.v(this.toString(), "Exiting decompress constructor."); } @Override protected void onPreExecute() { Log.v(this.toString(), "Inside onPreExecute."); pd = new ProgressDialog(mContext); pd.setTitle("Unzipping folder."); pd.setMessage("Unzip in progress."); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); Log.v(this.toString(), "Showing dialog and exiting."); pd.show(); } @Override protected Boolean doInBackground(Void... params) { //unzip operation goes here. unzipDest = something; //unzip destination is set here. if(unzip operation is successful) { result = true; index = url pointing to location of unzipped folder. } else { result = false; } } @Override protected void onPostExecute(Boolean result) { if(result) { if(pd != null) { pd.setTitle("Success"); pd.setMessage("folder is now ready for use."); pd.show(); pd.dismiss(); pd = null; Log.v(this.toString(), "Unzipped."); index = unzipDest + "/someURL"; Log.v(this.toString(), "index present in: " + index); } } else { pd = ProgressDialog.show(mContext, "Failure", "Cannot unzip."); pd.dismiss(); } } }

Problemas que estoy enfrentando:
1. El valor de unzipDest e index , actualizado en doInBackground , permanece nulo para Unzip y todos sus objetos. ¿Cómo puedo garantizar que los valores permanezcan actualizados?
2. Sé que doInBackground ocurre en un hilo separado del hilo principal de UI. ¿Eso significa que los valores actualizados en el nuevo hilo se perderán una vez que ese hilo retorne?


¿Cómo puedo garantizar que los valores permanezcan actualizados?

Se actualizarán ya que son variables miembro. Sin embargo, dado que AsyncTask es asincrónico, es posible que aún no se actualicen cuando los revises. Puede usar una interface para crear una devolución de llamada cuando se actualicen estos valores. Esta respuesta SO cubre cómo hacer esto

¿Eso significa que los valores actualizados en el nuevo hilo se perderán una vez que ese hilo retorne?

No, no deberían estar "perdidos". Probablemente no hayan sido cambiados en AsyncTask cuando los revises.

Como este no es su código real, no puedo verlo cuando intenta acceder a ellos, pero puede usar el método de interface o llamar a las funciones que necesitan estos valores en onPostExecute() . También puede hacer una comprobación null antes de intentar acceder a ellos. Depende de la funcionalidad y el flujo que necesite y cuál es la mejor manera. Espero que ayude.

Editar

En la respuesta a la que me he vinculado, le dices a la Activity que implements AsyncResponse esa interface y anulas sus métodos con implements AsyncResponse en tu declaración de Activity después de crear la interface class separada

public class MainActivity implements AsyncResponse{

entonces, en su Activity aún, anula el método que declaró en esa clase (proceso void processFinish(String output); )

@Override void processFinish(String output){ // using same params as onPostExecute() //this you will received result fired from async class of onPostExecute(result) method. }

luego se llama a onPostExecute() cuando el oyente ve que se hace con delegate.processFinish(result); delegate es una instancia de AsyncResponse (su clase de interfaz)

public class AasyncTask extends AsyncTask{ public AsyncResponse delegate=null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); }

Ejemplo de Interface tomado de la respuesta vinculada anterior y ajustado / comentado para mayor claridad. Así que asegúrese de votar esa respuesta si ayuda a alguien.