内部类可以访问但不能更新值 - AsyncTask [英] Inner class can access but not update values - 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. unzipDest
和 index
的值,在 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);
delegate
是AsyncResponse
的一个实例(你的接口类)
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屋!