【问题标题】:Android BitmapFactory decodeFile is called before it should beAndroid BitmapFactory decodeFile 在它应该被调用之前被调用
【发布时间】:2011-08-26 18:15:44
【问题描述】:

我正在尝试在 ListView 中显示图像的缩略图。这些图像位于我的 SDCard 上的 Camera 文件夹中。我正在使用 BitmapFactory.decodeFile 读取图像。我想在文件被解码时显示一个 ProgressDialog。我试图先显示 ProgressDialog,然后在 for 循环中调用 decodeFile。直到 for 循环之后才会显示 ProgressDialog。在显示 ProgressDialog 之前,对 decodeFile 的调用似乎正在运行。

如何在我的 for 循环之前显示 ProgressDialog?

公共类 ActivityProgressBar 扩展 ListActivity {

private Vector<RowFileData> fileDataDisplay = null;     
RowFileData fileData;
ProgressDialog progressDialog = null;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list);        
    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading thumbnails...");
    fileDataDisplay = new Vector<RowFileData>();
    File currentDirectory = new File("/mnt/sdcard/dcim/camera");
    File[] currentDirectoryFileList = currentDirectory.listFiles();
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inSampleSize = 16;
    progressDialog.show();
    for(int i=0; i<currentDirectoryFileList.length; i++)
    {
        File currentDirectoryFile = currentDirectoryFileList[i];
        fileData = new RowFileData(BitmapFactory.decodeFile(currentDirectoryFile.getPath(), opts), currentDirectoryFile.getPath());
        fileDataDisplay.add(fileData);
        Log.v("myLog", "inside for loop");
    }
}   

private class RowFileData 
{
   protected Bitmap rowBitmap;
   protected String rowFileName;
   RowFileData(Bitmap bitmapPreview, String fileName)
   {
       rowBitmap = bitmapPreview;
       rowFileName = fileName;
   }
}

}

我已经注释掉了对 progressDialog.dismiss() 的调用,以验证 ProgressDialog 是否在 for 循环之后显示。为了便于阅读,我删除了在 ListView 中显示图像的代码行。我用我的日志验证了我仍在 for 循环中。

谢谢

【问题讨论】:

    标签: java android bitmapfactory


    【解决方案1】:

    您还可以使用 asynctask 在后台解码位图并在前面显示进度对话框。完成解码位图后,只需禁用进度对话框。 Android - AsyncTaskTutorial 帮助你。谢谢。

    【讨论】:

    • 谢谢,这个教程很有帮助。我没有意识到Android中的主线程是UI线程!我希望首先显示进度对话框,并在位图文件被解码时保持显示。我在一本名为 Pro Android 的书中找到了一个很好的例子。我将在下面发布我的最终答案。
    【解决方案2】:

    我建议查看延迟加载您的图像。在另一篇 SO 帖子中有一个很好的示例,我刚刚为此目的实现了它,并且效果很好。

    Lazy load of images in ListView

    【讨论】:

      【解决方案3】:

      我希望在解码位图文件时显示进度对话框并保持显示。另外,我没有意识到Android中的主线程是UI线程,并且在主线程上进行处理时UI被冻结!我使用了后台线程,现在进度对话框正确显示:

      公共类 ActivityProgressBar 扩展 ListActivity {

      private Vector<RowFileData> fileDataDisplay = null;     
      RowFileData fileData;
      ProgressDialog progressDialog = null;
      
      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.list);        
          progressDialog = new ProgressDialog(this);
          progressDialog.setMessage("Loading thumbnails...");
          fileDataDisplay = new Vector<RowFileData>();
          File currentDirectory = new File("/mnt/sdcard/dcim/camera");
          BitmapFactory.Options opts = new BitmapFactory.Options();
          opts.inSampleSize = 16;
          File[] currentDirectoryFileList = currentDirectory.listFiles();
          progressDialog.show();
          readThumbnails(currentDirectoryFileList, opts);
      }   
      
      private void readThumbnails(final File[] currentDirectoryFileList, final BitmapFactory.Options opts) 
      {
          Thread backgroundThread = new Thread()
          {
              public void run()
              {
                  try
                  {
                      for(int i=0; i<currentDirectoryFileList.length; i++)
                      {
                          File currentDirectoryFile = currentDirectoryFileList[i];
                          fileData = new RowFileData(BitmapFactory.decodeFile(currentDirectoryFile.getPath(), opts), currentDirectoryFile.getPath());
                          fileDataDisplay.add(fileData);
                          Log.v("myLog", "inside for loop");
                      }
                      uiCallback.sendEmptyMessage(0);
                  }
                  catch(Exception ex)
                  {
                      Log.v("myLog", ex.toString());
                  }
              }
          };
          backgroundThread.start();
      }
      
      private Handler uiCallback = new Handler()
      {
          @Override
          public void handleMessage(Message emptyMessage)
          {
              progressDialog.dismiss();
          }
      };
      
      private class RowFileData 
      {
         protected Bitmap rowBitmap;
         protected String rowFileName;
         RowFileData(Bitmap bitmapPreview, String fileName)
         {
             rowBitmap = bitmapPreview;
             rowFileName = fileName;
         }
      }
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多