内部类可以访问但不能更新值 - AsyncTask
Posted
技术标签:
【中文标题】内部类可以访问但不能更新值 - AsyncTask【英文标题】:Inner class can access but not update values - AsyncTask 【发布时间】:2013-09-02 06:25:48 【问题描述】:我正在尝试使用 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
和index
的值,在doInBackground
中更新,对Unzip
及其所有对象保持为空。如何确保值保持更新?
2. 我知道 doInBackground 发生在与主 UI 线程分开的线程中。这是否意味着一旦该线程返回,新线程中更新的任何值都将丢失?
【问题讨论】:
【参考方案1】:如何确保这些值保持更新?
它们将被更新,因为它们是成员变量。但是,由于AsyncTask
是异步的,因此在您检查它们时它们可能尚未更新。当这些值更新时,您可以使用interface
创建回调。 This SO answer covers how to do this
这是否意味着一旦该线程返回,新线程中更新的任何值都将丢失?
不,他们不应该“迷失”。当您检查它们时,它们可能只是在AsyncTask
中没有更改。
由于这不是您的实际代码,当您尝试访问它们时我看不到它们,但您可以使用interface
方法或在onPostExecute()
中调用需要这些值的函数。您还可以在尝试访问它们之前进行null
检查。它仅取决于您需要的功能和流程,哪个是最佳方式。希望对您有所帮助。
编辑
在我链接的答案中,您告诉Activity
,您将使用该interface
,并在创建单独的interface class
后,在Activity
声明中用implements AsyncResponse
覆盖其方法
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.
然后当侦听器看到它已完成 delegate.processFinish(result);
时,会在 onPostExecute()
中调用 delegate
是 AsyncResponse
的实例(您的接口类)
public class AasyncTask extends AsyncTask
public AsyncResponse delegate=null;
@Override
protected void onPostExecute(String result)
delegate.processFinish(result);
Interface
示例取自上面的链接答案,并为清楚起见进行了调整/评论。因此,如果它对任何人有帮助,请务必支持该答案。
【讨论】:
不错的答案。 OP - 一般来说,您可能想根据 Java 标准阅读嵌套类的规则和类型:docs.oracle.com/javase/tutorial/java/javaOO/nested.html @codeMagic:感谢您的回复。在workThread.execute()
中解压操作成功完成后,我希望能够访问其url存储在index
中的文件。在您链接到的问题中,我不明白接口AsyncResponse
是如何初始化的。你能解释一下吗?谢谢。
@Sriram 我已编辑。我希望这能澄清一点。请尝试一下,并在遇到困难时询问。
@codeMagic: 如何初始化delegate
?在上面的 sn-p 中是null
。我还对问题进行了更多编辑。如果解压成功,我需要从解压后的文件夹中访问文件。但是,因为解压缩是由AsyncTask
执行的,所以workThread.execute()
之后的行甚至在解压缩之前就被执行,导致NullExceptions
。在进行解压缩操作时,我需要暂停 UI。那么AsyncTask
是该工作的最佳人选还是应该在另一个活动中进行解压缩?
你可以从 url ***.com/questions/12575068/…看到委托的初始化以上是关于内部类可以访问但不能更新值 - AsyncTask的主要内容,如果未能解决你的问题,请参考以下文章