Внутренний класс может получить доступ, но не обновлять значения - AsyncTask

Я пытаюсь распаковать папку с помощью Android AsyncTask. Класс (называемый Decompress) является внутренним классом Unzip, где сам Unzip является классом non-Activity. Псевдокод:

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

Проблемы, с которыми я столкнулся:
1. Значение unzipDest и index, обновленное в doInBackground, остается равным нулю для Unzip и всех его объектов. Как я могу гарантировать, что значения будут обновляться?
2. Я знаю, что doInBackground происходит в потоке отдельно от основного потока пользовательского интерфейса. Означает ли это, что любые значения, обновленные в новом потоке, будут потеряны после того, как поток вернется?

Ответы

Ответ 1

Как я могу гарантировать, что значения остаются обновленными?

Они будут обновляться, поскольку они являются переменными-членами. Однако, поскольку AsyncTask является асинхронным, они могут не обновляться, когда вы их проверяете. Вы можете использовать interface для создания обратного вызова при обновлении этих значений. Этот ответ SO описывает, как это сделать

Означает ли это, что любые значения, обновленные в новом потоке, будут потеряны после того, как поток вернется?

Нет, они не должны быть "потеряны". Вероятно, они просто не были изменены в AsyncTask, когда вы их проверяете.

Так как это не ваш фактический код, я не вижу, когда вы пытаетесь получить к ним доступ, но вы можете использовать метод interface или вызывать функции, которым эти значения нужны в onPostExecute(). Вы также можете выполнить проверку null перед тем, как попытаться получить к ним доступ. Это зависит только от функциональности и потока, которые вам нужны, что является лучшим способом. Надеюсь, что это поможет.

Edit

В ответе, с которым я связан, вы указываете Activity, что вы будете использовать этот interface и переопределите его метод с implements AsyncResponse в своем объявлении Activity после создания отдельного interface class

public class MainActivity implements AsyncResponse{

то в вашем Activity все еще вы переопределите метод, который вы объявили в этом классе (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.
   }

то это вызывается в onPostExecute(), когда слушатель видит, что это делается с помощью delegate.processFinish(result); delegate - это экземпляр AsyncResponse (ваш класс интерфейса)

    public class AasyncTask extends AsyncTask{
public AsyncResponse delegate=null;

   @Override
   protected void onPostExecute(String result) {
      delegate.processFinish(result);
   }

interface пример, взятый из приведенного выше ответа и скорректированный/прокомментированный для ясности. Поэтому обязательно поддержите этот ответ, если он кому-то поможет.