在AsyncTask的doInBackground()方法中运行FileOutputStream操作不会成功执行

时间:2015-09-03 21:08:46

标签: java android bitmap android-asynctask fileoutputstream

我使用AsyncTask作为内部类来保存位图。但是FileOutputStream操作不起作用。如果我在UI线程的方法中运行相同的代码代码运行,我能够成功保存位图。

我知道doInBackground()方法确实执行,并且onPostExecute()方法也被执行。

此外,如果我获取传递给AsyncTask的输入流,并尝试解码它以设置imageView,它不起作用。但是如果我在AsyncTask之外使用相同的代码就可以了。

我按如下方式实现了AsyncTask,并且没有记录第2和第3个日志语句,因此我知道某些内容未正常运行:

public class SaveImageToInternalStorage extends AsyncTask {

    InputStream bitmap;
    String PICTURE_KEY;

    public SaveImageToInternalStorage1(final InputStream bitmap, final String PICTURE_KEY) {
        this.bitmap = bitmap;
        this.PICTURE_KEY = PICTURE_KEY;



      }


        @Override
        protected Object doInBackground(Object[] params) {
            FileOutputStream fos;
            try {

                fos =  picture_chooser.this.openFileOutput(PICTURE_KEY, MODE_PRIVATE);

              Bitmap bitmap2 = BitmapFactory.decodeStream(bitmap);
                Log.v("saveBitmap", " first log statement");  ////This gets logged
                bitmap2.compress(Bitmap.CompressFormat.WEBP, 85, fos);
                 Log.v("saveBitmap", " second log statement");  // This is not logged
                fos.close();

              Log.v("saveBitmap", " third log statement"); // This is not logged
            } catch (Exception e) {
                Log.e("saveToInternalStorage()", e.getMessage());

            }

            return null;
        }


        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
   Log.v("saveBitmap", " onPostExecute log statement");  // This is logged
            imageViewSetter(bitmap);

        }
    }


    //runs in the wrapper class 
      public void imageViewSetter(InputStream inputStream) {
            imageView.setImageBitmap(BitmapFactory.decodeStream(inputStream)); //this does not set the imageView 

        }

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

从Android参考here

查看此示例

我在下面为你重新创建了代码

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
 protected Long doInBackground(URL... urls) {
     int count = urls.length;
     long totalSize = 0;
     for (int i = 0; i < count; i++) {
         totalSize += Downloader.downloadFile(urls[i]);
         publishProgress((int) ((i / (float) count) * 100));
         // Escape early if cancel() is called
         if (isCancelled()) break;
     }
     return totalSize;
 }

 protected void onProgressUpdate(Integer... progress) {
     setProgressPercent(progress[0]);
 }

 protected void onPostExecute(Long result) {
     showDialog("Downloaded " + result + " bytes");
 }
}

请注意,顶部的类声明后跟

<URL, Integer, Long> 

接下来,查看类中三个overriden方法中的每一个。您会注意到URL引用传递给doInBackground的参数,Integer是onProgressUpdate输出的内容,Long是doInBackground方法返回的onPostExecute < / p>

从此你可以看到AsyncTask应该按如下方式使用

doInBackground - 传递你想要做的任何事情。此方法在后台线程上完成所需的工作。此方法需要将已完成的对象返回到onPostExecute,您可以在此处捕获已完成工作的结果,并根据需要更新UI。 onProgressUpdate是可选的,您无需在此处执行任何操作。