Drawable cache problem, display definition,
Resource. getdrawable will return drawable Based on the ID, and then cache the drawable. See the following code snippet:
InputStream is = mAssets.openNonAsset( value.assetCookie, file, AssetManager.ACCESS_STREAMING); // System.out.println("Opened file " + file + ": " + is); dr = Drawable.createFromResourceStream(this, value, is, file, null); is.close();
dr.setChangingConfigurations(value.changingConfigurations); cs = dr.getConstantState(); if (cs != null) { if (mPreloading) { sPreloadedDrawables.put(key, cs); } else { synchronized (mTmpValue) { //Log.i(TAG, "Saving cached drawable @ #" + // Integer.toHexString(key.intValue()) // + " in " + this + ": " + cs); mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs)); } } }
The cache mechanism is well designed and uses a weak reference mechanism to avoid memory overflow. However, this method is relatively honest. If the resource is a bitmap, the source image will generate a large one. To make the program clearer on different screens and the memory occupied by the image is not too large, different images are usually loaded based on different screens, but the package size is increased again, generally, we will use the following solution:
Only one maximum definition graph is provided. The image is scaled according to the current screen size when the program is running.
One disadvantage of this method is that a large image is first loaded during loading, and then a small image is generated based on the large image. The memory peak is two images. Is there any way to use a cell phone with insufficient memory? The following is a solution:
private BitmapDrawable getDrawable(int id) {int width = AppTools.getSreenSize(this, true);int height = AppTools.getSreenSize(this, false);BitmapFactory.Options opts = new BitmapFactory.Options();opts.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), id, opts);opts.inSampleSize = AppTools.computeSampleSize(opts, -1,(int) (width * height));opts.inJustDecodeBounds = false;Bitmap bitmap = null;try {bitmap = BitmapFactory.decodeResource(getResources(), id, opts);} catch (OutOfMemoryError e) {}if (bitmap == null) {return null;}return new BitmapDrawable(bitmap);}
First, obtain the image width and height, calculate the sample size based on the target width and height, and then read the image.
BitmapFactory.Options opts = new BitmapFactory.Options();opts.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), id, opts);