La clase interna puede acceder pero no actualizar los valores - AsyncTask

Resuelto Sriram asked hace 54 años • 1 respuestas

Estoy intentando descomprimir una carpeta usando el archivo AsyncTask. La clase (llamada Descomprimir) es una clase interna de la Unzipcual 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 unzipDesty index, actualizado en doInBackground, permanece nulo para Unziptodos 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?

Sriram avatar Jan 01 '70 08:01 Sriram
Aceptado

¿Cómo puedo asegurarme de que los valores permanezcan actualizados?

Se actualizarán ya que son variables miembro. Sin embargo, dado que AsyncTaskson asincrónicos, es posible que aún no se hayan actualizado cuando los revise. Puede utilizar un interfacepara 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 interfacemétodo o llamar a las funciones que necesitan estos valores onPostExecute(). También puedes hacer una nullverificació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 Activityque usará eso interfacey anulará sus métodos implements AsyncResponseen su Activitydeclaración después de crear el archivo separado.interface class

public class MainActivity implements AsyncResponse{

luego, en tu Activityimagen 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); delegatees 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);
   }

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

codeMagic avatar Aug 29 '2013 17:08 codeMagic