简体   繁体   English

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

[英]Inner class can access but not update values - AsyncTask

I am trying to unzip a folder using Android's AsyncTask . 我正在尝试使用Android的AsyncTask解压缩文件夹。 The class (called Decompress) is an inner class of Unzip where Unzip itself is a non-Activity class. 该类(称为Decompress)是Unzip的内部类,其中Unzip本身是非Activity类。 The pseudo-code is: 伪代码为:

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

Problems I am facing: 我面临的问题:
1. The value of unzipDest and index , updated in doInBackground , remain null to Unzip and all its objects. 1.在doInBackground更新的unzipDestindex值对于Unzip及其所有对象保持为空。 How can I ensure that the values remain updated? 如何确保这些值保持更新?
2. I know that doInBackground occurs in a thread separate from the main UI thread. 2.我知道doInBackground发生在与主UI线程分开的线程中。 Does that mean that any values updated in the new thread will be lost once that thread returns? 这是否意味着一旦该线程返回,新线程中更新的所有值都会丢失?

How can I ensure that the values remain updated? 如何确保这些值保持更新?

They will be updated since they are member variables. 由于它们是成员变量,因此将被更新。 However, since AsyncTask is asynchrounous, they might not be updated yet when you check them. 但是,由于AsyncTask是异步的,因此当您检查它们时可能尚未更新。 You can use an interface to create a callback when these values are updated. 这些值更新后,您可以使用interface来创建回调。 This SO answer covers how to do this 这样的答案涵盖了如何做到这一点

Does that mean that any values updated in the new thread will be lost once that thread returns? 这是否意味着一旦该线程返回,新线程中更新的所有值都会丢失?

No they shouldn't be "lost". 不,他们不应该“迷路”。 They probably just haven't been changed in the AsyncTask when you check them. 在检查它们时,它们可能只是未在AsyncTask进行更改。

Since this isn't your actual code I can't see when you are trying to access them but you can use the interface method or call the functions that need these values in onPostExecute() . 由于这不是您的实际代码,因此当您尝试访问它们时无法看到,但是您可以使用interface方法或在onPostExecute()调用需要这些值的函数。 You also can do a null check before trying to access them. 您也可以在尝试访问它们之前进行null检查。 It just depends on the functionality and flow that you need as to which is the best way. 最好取决于您所需的功能和流程。 Hope that helps. 希望能有所帮助。

Edit 编辑

In the answer I linked to, you tell the Activity that you will use that interface and override its method(s) with implements AsyncResponse in your Activity declaration after creating the separate interface class 在我链接的答案中,您告诉Activity您将使用该interface并在创建单独的interface class后在Activity声明中使用implements AsyncResponse覆盖其方法。

public class MainActivity implements AsyncResponse{

then, in your Activity still, you override the method you declared in that class ( void processFinish(String output); ) 然后,仍然在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.
   }

then this is called in onPostExecute() when the listener sees that it is done with delegate.processFinish(result); 然后,当侦听器发现已使用delegate.processFinish(result);进行处理时,将在onPostExecute()调用此方法delegate.processFinish(result); delegate is an instance of AsyncResponse (your interface class) delegateAsyncResponse的实例(您的接口类)

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

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

Interface example taken from linked answer above and adjusted/commented for clarity. Interface示例摘自上面的链接答案,为清晰起见对其进行了调整/注释。 So be sure to upvote that answer if it helps anyone. 因此,如果对任何人有帮助,请确保对该答案进行投票。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM