我正在尝试使用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线程分开的线程中。这是否意味着一旦该线程返回,新线程中更新的任何值都将丢失?
答案 0 :(得分:14)
如何确保值保持更新?
它们将被更新,因为它们是成员变量。但是,由于AsyncTask
是异步的,因此在检查时它们可能尚未更新。更新这些值时,可以使用interface
创建回调。 This SO answer covers how to do this
这是否意味着一旦该线程返回,新线程中更新的任何值都将丢失?
不,他们不应该“迷失”。当你检查它们时,它们可能只是在AsyncTask
中没有被更改过。
由于这不是您的实际代码,我在您尝试访问它们时看不到,但您可以使用interface
方法或在onPostExecute()
中调用需要这些值的函数。在尝试访问它们之前,您还可以进行null
检查。它取决于您需要的功能和流程,哪种是最佳方式。希望有所帮助。
修改强>
在我链接的答案中,您告诉Activity
您将使用interface
并在implements AsyncResponse
声明后使用Activity
覆盖其方法创建单独的interface class
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.
}
然后当监听器看到它已完成onPostExecute()
delegate.processFinish(result);
delegate
(您的接口类)
AsyncResponse
中调用此方法
public class AasyncTask extends AsyncTask{
public AsyncResponse delegate=null;
@Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
Interface
示例取自上面的链接答案并进行了调整/评论,以便明确说明。所以,如果对任何人都有帮助,请务必提出答案。