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.