2

我有这样的方法:

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 并移动到下一个屏幕。

这里有什么问题?

4

3 回答 3

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

你应该先调用 super

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

Asynctask 必须在 UI 线程上加载。加载异步任务时,会在 ui 线程上调用异步任务 onPreExecute()。之后 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 线程上调用。后台计算的结果作为参数传递给该步骤。

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

于 2013-04-18T05:25:22.227 回答
1

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

zhelper.unzip(xapkFilePath, exportDirectoryFilepath);
于 2013-04-18T05:58:30.403 回答
0

我通过声明 doInBackground 和 onPostExecute 同步解决了一个非常相似的问题。
(...)
protected synchronized Boolean doInBackground(Void... params)
{...}
protected synchronized void onPostExecute(Boolean result) {...}
(...)
在我的例子中, doInBackground() 首先进入(应该)但是在 doInBackground() “技术上”完成之前调用了 onPostExecute() (我不知道为什么 - 也许我的解压缩库对象有自己的线程并且没有阻止 doInBackground() 方法)。同步方法解决了问题(当然,不是没有性能后果)

于 2018-05-13T18:18:44.330 回答