【问题标题】:Android: ASyncTask's behavior contrary to documentationAndroid:ASyncTask 的行为与文档相反
【发布时间】:2017-08-11 07:50:50
【问题描述】:

第一次写AsyncTask,我似乎有一个微妙的设计缺陷,使ProgressDialogProgressBar,甚至Log.d()都无法正常工作。我怀疑我实际上并没有创建一个新线程/任务。

简短:症状

  • 在构造函数中创建了一个ProgressDialog,代码命令Android在onPreExecute()中显示它,但对话框从未显示。

  • onProgressUpdate() 应该在我从doInBackground() 中调用publishProgress() 时执行,对吗?好吧,它没有。相反,它会在 doInBackground() 完成时执行。

长期:调查

我通过模拟器验证的事情,如果可能的话,在手机上验证:

  • onPreExecute() 肯定被调用

    • 直到doInBackground()完成后进度条才会重置

    • update_dialog.show() 肯定会执行,但是除非我删除onPostExecute() 中的.dismiss(),否则不会出现对话框;我想对话框就像进度条一样,直到 doInBackground() 完成后才会显示,但自然会立即被解雇

    • 当不涉及计算时,代码会愉快地显示对话框

  • doInBackground() 肯定会调用publishProgress()

    • 当它执行时,onProgressUpdate() 不会立即执行!也就是说,我在函数中有一个断点,直到doInBackground() 完成后调试器才会停在那里! (也许这是调试器的现象,而不是doInBackground(),但我在移动设备上观察到相同的症状)

    • 进度条会更新...仅在doInBackground() 完成所有操作后

    • 同样,Log.d() 数据仅在 doInBackground() 完成所有操作后才会显示在 Android Monitor 中

  • 当然,该对话框不会出现在模拟器或设备上(除非我从onPostExecute() 中删除.dismiss()

谁能帮忙找出问题?理想情况下,我想要一个工作对话框,但由于 Android 已经弃用它,无论如何我都可以使用工作进度条。

代码

这里是要点,不包括计算的细节和c。

我从主线程调用AsyncTask

if (searching) { // this block does get executed!
   Compute_Task my_task = new Compute_Task(overall_context, count);
   my_task.execute(field, count, max_x, max_y);
   try { result = my_task.get(); } catch (Exception e) { }
}

AsyncTask 本身:

private class Compute_Task extends AsyncTask<Object, Integer, Integer> {

   public Compute_Task(Context context, int count) {
      super();
      current_positions = 0;
      update_dialog = new ProgressDialog(context);
      update_dialog.setIndeterminate(true);
      update_dialog.setCancelable(false);
      update_dialog.setTitle("Thinking");
      update_dialog.setMessage("Please wait");
   }

   protected void onPreExecute() {
      super.onPreExecute();
      update_dialog.show();
      ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar));
      pb.setMax(base_count);
      pb.setProgress(0);
   }

   protected void onPostExecute() {
      super.onPostExecute();
      update_dialog.dismiss();
   }

   protected void onProgressUpdate(Integer... values) {
      super.onProgressUpdate(values);
      ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar));
      pb.setMax(base_count);
      pb.incrementProgressBy(1);
      Log.d(tag, values[0].toString());
   }

   protected Integer doInBackground(Object... params) {
      Integer result = compute_scores(
         (boolean[][]) params[0], (Integer) params[1], (Integer) params[2], (Integer) params[3], 0)
      );
      return result;
   }

   public int compute_scores(boolean[][] field, int count, int max_x, int max_y, int level) {
      int result, completed = 0;
      switch(count) {
         // LOTS of computation goes on here,
         // including a recursive call where all params are modified
         if (level == 0)
            publishProgress(++completed);
      }
   }

   ProgressDialog update_dialog;

}

【问题讨论】:

    标签: recursion android-asynctask android-progressbar


    【解决方案1】:

    事实证明,这与给定here 的问题基本相同。 “致命”行是这一行:

    try { result = my_task.get(); } catch (Exception e) { }
    

    显然这会使 UI 线程进入深度睡眠。 除非愿意暂停 UI 线程,否则不应将 get()AsyncTask 一起使用。我们必须在 onPostExecute() 中施展一点魔法。

    虽然发现这是重复的,但是直到我写完才发现,因为我没有意识到线程被阻塞了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多