内部类可以访问但不能更新值 - AsyncTask [英] Inner class can access but not update values - AsyncTask

查看:19
本文介绍了内部类可以访问但不能更新值 - AsyncTask的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Android 的 AsyncTask 解压缩文件夹.该类(称为 Decompress)是 Unzip 的内部类,其中 Unzip 本身是一个非活动类.伪代码为:

I am trying to unzip a folder using Android's AsyncTask. The class (called Decompress) is an inner class of Unzip where Unzip itself is a non-Activity class. 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();
            }
        }
    }   

我面临的问题:
1. unzipDestindex 的值,在 doInBackground 中更新,对于 Unzip 及其所有对象保持 null.如何确保值保持更新?
2. 我知道 doInBackground 发生在与主 UI 线程分开的线程中.这是否意味着一旦该线程返回,新线程中更新的任何值都会丢失?

Problems I am facing:
1. The value of unzipDest and index, updated in doInBackground, remain null to Unzip and all its objects. How can I ensure that the values remain updated?
2. I know that doInBackground occurs in a thread separate from the main UI thread. 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?

它们将被更新,因为它们是成员变量.但是,由于 AsyncTask 是异步的,当您检查它们时,它们可能尚未更新.您可以使用 interface 在这些值更新时创建回调.这个答案涵盖如何做到这一点

They will be updated since they are member variables. However, since AsyncTask is asynchrounous, they might not be updated yet when you check them. You can use an interface to create a callback when these values are updated. 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?

不,他们不应该迷失".当您检查它们时,它们可能只是没有在 AsyncTask 中更改.

No they shouldn't be "lost". They probably just haven't been changed in the AsyncTask when you check them.

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

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(). You also can do a null check before trying to access them. It just depends on the functionality and flow that you need as to which is the best way. Hope that helps.

编辑

在我链接的答案中,您告诉 Activity 您将使用该 interface 并使用 implements AsyncResponse 覆盖其方法> 在你的 Activity 声明中创建单独的 interface class

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

public class MainActivity implements AsyncResponse{

然后,在您的 Activity 中,您仍然覆盖您在该类中声明的方法 (void processFinish(String output);)

then, in your Activity still, you override the method you declared in that class (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); delegateAsyncResponse 的一个实例(你的接口类)

then this is called in onPostExecute() when the listener sees that it is done with delegate.processFinish(result); delegate is an instance of AsyncResponse (your interface class)

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

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

Interface 示例取自上面链接的答案并为清晰起见进行了调整/评论.因此,如果该答案对任何人有帮助,请务必点赞.

Interface example taken from linked answer above and adjusted/commented for clarity. So be sure to upvote that answer if it helps anyone.

这篇关于内部类可以访问但不能更新值 - AsyncTask的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆