在doInBackground完成之前调用onPostExecute - 异步任务

时间:2013-04-18 05:18:52

标签: android android-asynctask

我有这样的方法:

public void extractFiles() {

    AsyncTask<Void, Void, Boolean> extractionTask = new AsyncTask<Void, Void, Boolean>() {

        @Override
        protected void onPreExecute() {
        progressDialog = new ProgressDialog(Activity.this);
        progressDialog.setCancelable(false);
        progressDialog.setMessage("Extracting Files Please wait...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setProgress(0);
        progressDialog.show();
        super.onPreExecute();
        }

        @Override
        protected Boolean doInBackground(Void... params) {
        // TODO Auto-generated method stub
        String xapkFilePath = XAPKFilePath(Activity.this);
        String exportDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/"
            + Activity.this.getPackageName() + "/files/";
        File exportDirectoryFilepath = new File(exportDirectory);
        exportDirectoryFilepath.mkdirs();
        ZipHelper zhelper = new ZipHelper();


        System.out.println("In background called");
        zhelper.unzip(xapkFilePath, exportDirectoryFilepath);

        return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
            System.out.println("progress dialog dismissed");
        }
        if (result) {
            //start intent.
        }
        }

    };
    extractionTask.execute();
    }

public class ZipHelper {

    boolean zipError = false;

    public boolean isZipError() {
    return zipError;
    }

    public void setZipError(boolean zipError) {
    this.zipError = zipError;
    }

    public void unzip(String archive, File outputDir) {
    try {
        Log.d("control", "ZipHelper.unzip() - File: " + archive);
        ZipFile zipfile = new ZipFile(archive);
        for (Enumeration e = zipfile.entries(); e.hasMoreElements();) {
        ZipEntry entry = (ZipEntry) e.nextElement();

        System.out.println("OUTPUT DIR 1*" + outputDir);
        System.out.println("ENTRY IS " + entry);

        unzipEntry(zipfile, entry, outputDir);

        }
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzip() - Error extracting file " + archive + ": " + e);
        setZipError(true);
    }
    }

    private void unzipEntry(ZipFile zipfile, ZipEntry entry, File outputDir) throws IOException {
    if (entry.isDirectory()) {
        createDirectory(new File(outputDir, entry.getName()));
        return;
    }

    File outputFile = new File(outputDir, entry.getName());
    if (!outputFile.getParentFile().exists()) {
        createDirectory(outputFile.getParentFile());
        System.out.println("OUTPUT FILE IS " + outputFile.getParentFile());
    }

    Log.d("control", "ZipHelper.unzipEntry() - Extracting: " + entry);
    BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry));
    BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));
    try {
        IOUtils.copy(inputStream, outputStream);
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzipEntry() - Error: " + e);
        setZipError(true);
    } finally {
        outputStream.close();
        inputStream.close();
    }
    }

    private void createDirectory(File dir) {
    Log.d("control", "ZipHelper.createDir() - Creating directory: " + dir.getName());
    if (!dir.exists()) {
        if (!dir.mkdirs()) {
        throw new RuntimeException("Can't create directory " + dir);
        }
    } else {
        Log.d("control", "ZipHelper.createDir() - Exists directory: " + dir.getName());
    }
    }

}

在这里我调用类似extractFiles()的方法但是发生的事情甚至在doInBackground完成之前就是提取我正在显示微调器的文件,onPostExecute被调用并移动到下一个屏幕。 / p>

这里有什么问题?

3 个答案:

答案 0 :(得分:1)

public void extractFiles() {
     new TheTask().execute(params);
}
class TheTask extends AsyncTask<Void,Void,Void>
{ 
     .......
}

你应该先打电话给

  @Override
    protected void onPreExecute() 
      super.onPreExecute();
   }

必须在UI线程上加载Asynctask。 加载asynctask时,asictask onPreExecute()在ui线程上被输入。之后doInBAckground()在后台线程中运行。 doInBackground()的结果是onPostExecute()的参数。

执行异步任务时,任务将经历4个步骤:

  1. onPreExecute(),在执行任务之前在UI线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

  2. doInBackground(Params ...),在onPreExecute()完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数将传递给此步骤。计算结果必须由此步骤返回,并将传递回最后一步。此步骤还可以使用publishProgress(Progress ...)发布一个或多个进度单元。这些值发布在UI线程的onProgressUpdate(Progress ...)步骤中。

  3. onProgressUpdate(Progress ...),在调用publishProgress(Progress ...)后在UI线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。例如,它可用于为进度条设置动画或在文本字段中显示日志。

  4. onPostExecute(Result),在后台计算完成后在UI线程上调用。后台计算的结果作为参数传递给此步骤。

  5. http://developer.android.com/reference/android/os/AsyncTask.html

答案 1 :(得分:1)

检查doinbackground中的条件是否完全执行操作,如果执行则返回true,

zhelper.unzip(xapkFilePath, exportDirectoryFilepath);

答案 2 :(得分:0)

我通过声明doInBackground和onPostExecute同步来解决了一个非常类似的问题。
(...)
protected synchronized 布尔值doInBackground(Void ... params)
{...}
受保护的同步 void onPostExecute(布尔结果){...}
(...)
在我的情况下,doInBackground()首先进入(因为它应该)但在某种程度上onPostExecute()在doInBackground()“技术上”完成之前被调用(我无法弄清楚为什么 - 也许我的解压缩库对象有自己的线程并且没有阻塞doInBackground()方法)。同步方法解决了问题(当然,并非没有性能影响)