简体   繁体   中英

Running FileOutputStream operations in AsyncTask's doInBackground() method does not execute successfully

I am using an AsyncTask as an inner class to save a bitmap. But the FileOutputStream operation does not work. If I run the same code in a method in the UI thread the code runs and I am able to successfully save the bitmap.

I know that the doInBackground() method does execute and the onPostExecute() method gets executed as well.

Also, if I take the input stream which is passed to the AsyncTask, and try and decode it to set an imageView, it does not work. But if I use the same code outside of the AsyncTask it works.

I implemented the AsyncTask as follows and the 2nd and 3rd log statements do not get logged, so I know something is not running properly:

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 

        }

Any help would be greatly appreciated.

Have a look at this example from the Android reference here

I've recreated the code for you below

 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");
 }
}

Notice the class declaration at the top is followed by

<URL, Integer, Long> 

Next, look at each of the three overriden methods inside the class. You will notice that URL refers to the argument passed in to doInBackground , Integer is what is output by onProgressUpdate and Long is what is returned by your doInBackground method to onPostExecute

From this you can hopefully see that AsyncTask should be used as follows

doInBackground - pass in whatever it is you want to do some work on. This method does the work you want on a background thread. This method needs to return the finished object(s) to onPostExecute which is where you can catch the results of the work done and update the UI if you want to. onProgressUpdate is optional, you don't need to do anything here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM