Can someone please tell me where I'm going wrong with this piece of code? Basically I want the app to download a .png file, display it to the user and also save it to the sd card for future reference. It seems to be all going fine until the while ((len = webstream.read(buffer)) > 0)
part; as the debugger doesn't reach the breakpoint I've put in here, and I have a directory of empty .png files. I have the WRITE_EXTERNAL_STORAGE
permission declared in my Manifest.
protected class DownloadTask extends AsyncTask<String, Integer, Bitmap> {
@Override
protected Bitmap doInBackground(String... string) {
Bitmap d = null;
try {
DefaultHttpClient dhc = new DefaultHttpClient();
HttpGet request = new HttpGet(HTTP_BASE + string[0] + ".png");
HttpResponse response = dhc.execute(request);
BufferedInputStream webstream = new BufferedInputStream(response.getEntity().getContent());
d = BitmapFactory.decodeStream(webstream);
wri开发者_高级运维teToSd(string[0], webstream, d);
}
catch (Exception ex) { ex.printStackTrace(); }
return d;
}
private void writeToSd(String string, BufferedInputStream webstream, Bitmap d) {
try {
webstream.mark(3);
webstream.reset();
File f = new File(Environment.getExternalStorageDirectory() + SD_DIR);
f.mkdirs();
File f2 = new File(f, string + ".png");
f2.createNewFile();
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(f2));
int len;
byte[] buffer = new byte[1024];
while ((len = webstream.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
webstream.close();
//fos.flush();
fos.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
protected void onPostExecute(Bitmap result) {
if (result != null) {
iv.setImageBitmap(result);
vs.setDisplayedChild(1);
}
}
};
I don't know for sure, but it seems likely that there is something wrong with the re-reading of the InputStream, even though it's buffered. An image is quite a bit of data to hold in memory. Rather than doing
Fetch Image, Display Image, Store Image
you could try to
Fetch Image, Store Image, Display Image
This way you can write a full-sized image to disk (without having to buffer the stream and consume a lot of memory). Then, you can simply load the image from the sd card at the lowest sampling rate that works for your application, thus saving having a full-sized image ever in memory. Also, doing it this way would likely eliminate any issues you may or may not be having with the bufferedInputStream - I find them to be pretty finicky.
Unless you want the original stream bytes, you can write the bitmap out to disk using Bitmap.compress(format, quality, stream)
.
However, Hamy's answer is probably best from a memory conservation point of view.
精彩评论