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.