[英]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
更新的unzipDest
和index
值对于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) delegate
是AsyncResponse
的实例(您的接口类)
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.