The previous days have been for the picture memory overflow problem, check n more information, Google completely turned over all did not find a solution, when I was almost desperate when accidentally found a netizen of a tool class, holding the last hint of hope will code co come over to try a, the result makes me overjoyed. Hey, it's settled! I do not say how happy, listen to my slow way to the cause and consequences of it!
requirements: Download the picture down, display in space and support offline viewing
The first version of the code:
Read picture from local public Bitmap GETBITMAPFROMSD (String filename) { FileInputStream fi = null; Bufferedinputstream bi = null; Bitmap bp = null; try { fi = new FileInputStream (filename); bi = new Bufferedinputstream (FI); bp = Bitmapfactory.decodestream (BI); } catch (IOException e) { bp = null; } finally { try { if (bi! = null) { bi.close (); } if (fi! = null) { fi.close ();} } catch (IOException e) { bp = null; } } return BP; }
the problem arises, because the displayed picture is too large, so there will be outofmemoryexception. I think I can catch the exception to retrieve the picture and reload, so I want to find a solution from the Internet, what manual intervention GC, what will the picture weaken what use weak references to save the picture, some summed up particularly good (http://mzh3344258.blog.51cto.com/1823534 /804237), these methods I one by one try but the problem is still unresolved. Constantly oom, constantly try to recycle, error is not appear, but once the memory is too much will not show the picture, the default picture appears. Finally, I found the following tools from the Internet, help me to solve this problem, the specific URL forgot (thanks to the Netizen (*^__^*)), now the code is posted so that the next time to pick up
Public final class Bitmaputil {private static final size zero_size = new Size (0, 0); Private static final Options options_get_size = new options (); Private static final Options Options_decode = new options (); private static final byte[] LOCKED = new byte[0];//This object is used to maintain bitmap recycling order, ensuring that the last used picture is recycled private static final LinkedList C Ache_entries = new LinkedList (); Thread request creates a queue for picture private static final Queue Task_queue = new LinkedList (); Saves the key of the picture being processed in the queue, effectively prevents the duplicate addition to the request creation queue private static final Set Task_queue_index = new HashSet (); Cache bitmap private static final Map Img_cache_index = new HashMap (); Through the picture path, the picture size is private static int cache_size = 20; Number of cached pictures static {Options_get_size.injustdecodebounds = true; Initializes the Create picture thread and waits to process new thread () {{Setdaemon (true); public void Run () {synchronized (true) {Task_queue} {if (Task_queue.isempty ()) {try { Task_queue.wait (); }catch (Interruptedexception e) {e.printstacktrace (); }}} Queueentry entry = Task_queue.poll (); String key = CreateKey (Entry.path, Entry.width, entry.height); Task_queue_index.remove (key); CreateBitmap (Entry.path, Entry.width, entry.height); }}}.start (); public static Bitmap Getbitmap (String path, int width, int height) {if (path==null) {return null; } Bitmap Bitmap = null; try {if (cache_entries.size () >= cache_size) {destorylast (); } bitMap = Usebitmap (path, width, height); if (BitMap! = null &&!bitmap.isrecycled ()) {return bitMap; } bitMap = CreateBitmap (path, width, height); String key = CreateKey (path, width, height); Synchronized (LOCKED) {img_cache_index.put (key, BITMAP); Cache_entries.addfirst (key); }} catch (OutOfMemoryError err) {destorylast (); System.out.println (cache_size); return CreateBitmap (path, width, height); } return BITMAP; } public static Size Getbitmapsize (String path) {File File = new file (path); if (file.exists ()) {inputstream in = null; try {in = new FileInputStream (file); Bitmapfactory.decodestream (in, null, options_get_size); return new Size (Options_get_size.outwidth, options_get_size.outheight); } catch (FileNotFoundException e) {return zero_size; } finally {Closeinputstream (in); }} return zero_size; }//------------------------------------------------------------------private Methods//Add picture to queue header private static Bitmap Usebitmap (String path, int width, int height) {Bitmap Bitmap = null; String key = CreateKey (path, width, height); Synchronized (LOCKED) {bitMap = Img_cache_index.get (key); if (null! = BitMap) {if (Cache_entries.remove (key)) {Cache_entries.addfirst (key); }}} return bitMap; }//Recycle last picture private static void Destorylast () {synchronized (LOCKED) {String key = Cache_entries.removelast (); if (key.length () > 0) {Bitmap Bitmap = Img_cache_index.remove (key); if (BitMap! = null &&!bitmap.isrecycled ()) {bitmap.recycle (); BitMap = null; }}}}//Create key private static string CreateKey (string path, int width, int height) {if (null = = Path | | path.length ( ) = = 0) {return ""; } Return path + "_" + Width + "_" + height; }//through the picture path, Width height creates a Bitmap object private static Bitmap CreateBitmap (String path, int width, int height) {File File = new Fi Le (path); if (file.exists ()) {inputstream in = null; try {in = new FileInputStream (file); Size size = getbitmapsize (path); if (Size.equals (zero_size)) {return null; } int scale = 1; int a = Size.getwidth ()/width; int b = size.getheight ()/height; Scale = Math.max (A, b); Synchronized (options_decode) {options_decode.insamplesize = scale; Bitmap Bitmap = Bitmapfactory.decodestream (in, null, Options_decode); return BITMAP; }} catch (FileNotFoundException e) { LOG.V ("Bitmaputil", "createbitmap==" +e.tostring ()); } finally {Closeinputstream (in); }} return null; }//closes the input stream private static void Closeinputstream (InputStream in) {if (null! = in) {try {in.close (); } catch (IOException e) {log.v ("Bitmaputil", "closeinputstream==" +e.tostring ()); }}}//Picture size static class size {private int width, height; Size (int width, int height) {this.width = width; This.height = height; } public int getwidth () {return width; } public int getheight () {return height; }}//queue cache Parameter object static class Queueentry {public String path; public int width; public int height; }}
I only called the Getbitmap method when I used it, I passed the height width I needed to set and the local picture path, so I could automatically return bitmap to me, And when the capture to the oomerror of the LinkedList last picture is the first saved image to overflow and recovery is done, especially attention is here to catch the error exception is not obtained, Be sure to manually capture OutOfMemoryError you can handle (estimate these reasons everyone knows, so do not repeat, children's shoes refueling!) Method is always more than difficult O (∩_∩) o)
OutOfMemoryException solution for reading local pictures on Android side