La clase interna puede acceder pero no actualizar los valores - AsyncTask
Estoy intentando descomprimir una carpeta usando el archivo AsyncTask
. La clase (llamada Descomprimir) es una clase interna de la Unzip
cual Unzip en sí es una clase que no es Actividad. El pseudocó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 a los que me enfrento:
1. El valor de unzipDest
y index
, actualizado en doInBackground
, permanece nulo para Unzip
todos sus objetos. ¿Cómo puedo asegurarme de que los valores permanezcan actualizados?
2. Sé que doInBackground ocurre en un hilo separado del hilo principal de la interfaz de usuario. ¿Eso significa que cualquier valor actualizado en el nuevo hilo se perderá una vez que ese hilo regrese?
¿Cómo puedo asegurarme de que los valores permanezcan actualizados?
Se actualizarán ya que son variables miembro. Sin embargo, dado que AsyncTask
son asincrónicos, es posible que aún no se hayan actualizado cuando los revise. Puede utilizar un interface
para crear una devolución de llamada cuando se actualicen estos valores. Esta respuesta SO cubre cómo hacer esto.
¿Eso significa que cualquier valor actualizado en el nuevo hilo se perderá una vez que ese hilo regrese?
No, no deberían estar "perdidos". Probablemente simplemente no se hayan cambiado en elAsyncTask
los revisas.
Como este no es su código real, no puedo ver cuándo intenta acceder a ellos, pero puede usar el interface
método o llamar a las funciones que necesitan estos valores onPostExecute()
. También puedes hacer una null
verificación antes de intentar acceder a ellos. Solo depende de la funcionalidad y el flujo que necesite cuál es la mejor manera. Espero que ayude.
Editar
En la respuesta a la que me vinculé, le dice Activity
que usará eso interface
y anulará sus métodos implements AsyncResponse
en su Activity
declaración después de crear el archivo separado.interface class
public class MainActivity implements AsyncResponse{
luego, en tu Activity
imagen fija, anulas el método que declaraste en esa clase ( 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.
}
entonces esto se llama onPostExecute()
cuando el oyente ve que ha terminado y 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);
}
Interface
Ejemplo tomado de la respuesta vinculada anteriormente y ajustado/comentado para mayor claridad. Así que asegúrese de votar esa respuesta si ayuda a alguien.