social pharmacy d-pharm 1st year by Pragati K. Mahajan
Android memory and performance optimization
1. Downloaded from: justpaste.it/85hq5
Android memory and performance optimization
Android memory and performance optimization. This tutorial describes how to optimize the usage of memory and
optimize your performance in your Android application. The tutorial is based on Android Studio,android studio
course
1. Programming tips for providing highly responsive and fast
Android applications
1.1. Why you should be careful with Android resources
Android devices have less power than standard desktop or notebook computers. For this reason you must be
careful with memory consumption.
Especially on Android devices before Android 5.0 you want to avoid triggering the garbage collector of the Java
virtual machine. This results in a freeze of the Android runtime for about 200 ms. This can be a notable delay, if the
user is, for example, scrolling down a list.
1.2. Avoid unnecessary object allocation
Avoid creating unnecessary objects, especially in expensive places. Reuse objects if possible. Creating
unnecessary objects triggers the garbage collection more frequently, and this should be avoided.
For example avoid object creating in loops or in the onDraw() method of your custom view.
1.3. Use efficient data structures
Android provides several implementations of Sparse*Array classes. Consider the following code.
Map<Integer, String> map = new HashMap<Integer, String>();
Using this code results in unnecessary Integer objects created.
Android provides data structures which are more efficient for mapping values to other objects. If possible use these
objects, they avoid object creation as in the case of using HashMap. Object creation can be expensive and should
be avoided to reduce the number of times the garbage collector needs to run.
The table give examples for SparseArrays.
Table 1. Efficient memory structures
Memory structure Description
SparseArray<E> Maps integers to Objects, avoid the creation of Integer objects.
SparseBooleanArray Maps integers to booleans.
SparseIntArray Maps integers to integers
2. To improve the above example, prefer to use the following data structure.
SparseArray<String> map = new SparseArray<String>(); map.put(1, "Hello");
2. Handling bitmaps
Bitmaps can allocate lots of memory if loaded at full size. It is recommended to load the bitmaps in the desired size
into memory. Assume you have an application which displays an image in 100x100 dp, you should load the image
in exactly this size.
A common way is to first measure the bitmap without loading it via a flag passed to the BitmapFactory.
// instruct BitmapFactory to only the bounds and type of the image
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(),
R.id.myimage, options); // get width and height int imageHeight = options.outHeight;
int imageWidth = options.outWidth; // type of the image String imageType =
options.outMimeType;
Afterwards you can load the scaled version of the image. Android is really good in scaling images by a power of
two. You can use the following method (from the official Android documentation) to calculate the scale factor on a
basis of 2.
public static Bitmap decodeBitmapWithGiveSizeFromResource(Resources res, int resId,
int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check
dimensions final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId,
options); // Calculate inSampleSize options.inSampleSize =
calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with
inSampleSize set options.inJustDecodeBounds = false; return
BitmapFactory.decodeResource(res, resId, options); } public static int
calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image final int height = options.outHeight; final int
width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width >
reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; //
Calculate the largest inSampleSize value that is a power of 2 and keeps both //
height and width larger than the requested height and width. while ((halfHeight /
inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize
*= 2; } } return inSampleSize; }
This method can be used to assign the image to a view as demonstrated in the following example.
viewWidth = imageView.getWidth(); viewHeight = imageView.getHeight(); imageView.
imageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(),
R.id.myimage, viewWidth, viewHeight));
3. Using caches
3.1. Using a cache
A cache allows reusing objects which are expensive to create. If you load on object into memory, you can think of
this as a cache for the object. For example, if you downloading images from the Internet to display them in a list
you should hold them in memory to avoid that you download them several times.
3. At some point you need to recycle some of your objects, otherwise you run out of memory. A good approach to do
this, is to recycle the objects which have not been used the longest in your application.
The Android platform provides the LruCache class, as of API 12 (or in the support-v4 library).
The LruCache class provides a _least recently used cache _ (LRU cache) cache implementation. A LRU cache
keeps track of the usage of its members. It has a given size and if this size is exceeded, it removes the items which
have not be accessed the longest. This behavior is depicted in the following graphic.
The following example code demonstrates a possible implementation of the LruCache class for caching images.
public class ImageCache extends LruCache<String, Bitmap> { public ImageCache( int
maxSize ) { super( maxSize ); } @Override protected int sizeOf( String key, Bitmap
value ) { return value.getByteCount(); } @Override protected void entryRemoved(
boolean evicted, String key, Bitmap oldValue, Bitmap newValue ) {
oldValue.recycle(); } }
Its usage is simple and demonstrated by the following example code.
LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>();
For determining the initial size of the cache, it is good practice to determine the size based on the total memory
available on the device. For determining the available memory you can the MemoryClass. This is demonstrated
by the following code.
int memClass = ( ( ActivityManager) activity.getSystemService(
Context.ACTIVITY_SERVICE ) ).getMemoryClass(); int cacheSize = 1024 * 1024 *
memClass / 8; LruCache cache = new LruCache<String, Bitmap>( cacheSize );
3.2. Cleaning up your cache
As of API 14 you can override the onTrimMemory() method in Android components. This method is called by the
Android system asking you to cleanup your memory in case the Android system requires resources for foreground
processes.
4. And To more information visit:android course online