内部类可以访问但不能更新值 - AsyncTask

时间:2013-08-29 17:29:45

标签: java android multithreading android-asynctask

我正在尝试使用Android的AsyncTask解压缩文件夹。该类(称为Decompress)是Unzip的内部类,其中Unzip本身是非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中更新的indexdoInBackground的值对Unzip及其所有对象保持为空。如何确保值保持更新?
2.我知道doInBackground发生在与主UI线程分开的线程中。这是否意味着一旦该线程返回,新线程中更新的任何值都将丢失?

1 个答案:

答案 0 :(得分:14)

  

如何确保值保持更新?

它们将被更新,因为它们是成员变量。但是,由于AsyncTask是异步的,因此在检查时它们可能尚未更新。更新这些值时,可以使用interface创建回调。 This SO answer covers how to do this

  

这是否意味着一旦该线程返回,新线程中更新的任何值都将丢失?

不,他们不应该“迷失”。当你检查它们时,它们可能只是在AsyncTask中没有被更改过。

由于这不是您的实际代码,我在您尝试访问它们时看不到,但您可以使用interface方法或在onPostExecute()中调用需要这些值的函数。在尝试访问它们之前,您还可以进行null检查。它取决于您需要的功能和流程,哪种是最佳方式。希望有所帮助。

修改

在我链接的答案中,您告诉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示例取自上面的链接答案并进行了调整/评论,以便明确说明。所以,如果对任何人都有帮助,请务必提出答案。