Showing posts with label out-of-memory. Show all posts
Showing posts with label out-of-memory. Show all posts

Sunday, 27 April 2014

Common errors

Why should you know these?

Everyone wants to be an expert in Android development, and to be the expert in any development language you should know what kind of errors could arise and what are the reasons of errors/exceptions to solve them quickly.Also best developer is not that who has 3 to 5 years experience, but the best is that who knows what will happen if I use my logic in this way or that way, and will my logic work perfectly or it will arise some errors/exceptions.And this is the difference between Junior and Senior.Seniors predict the occurrence of errors/exceptions and avoid them using different approaches to develop applications rapidly.

1. Null Pointer Exception:

  • When we use an uninitialized variable or object we are creating.
  • When we use some layout view that is not in xml what we set in context.
  • Calling the instance method of a null object.
  • Accessing or modifying the field of a null object.
  • Taking the length of null as if it were an array.
  • Accessing or modifying the slots of null as if it were an array.
  • Throwing null as if it were a Throw-able value. 

OR

A NULL pointer is one that points to nowhere. When you dereference a pointer "p", you say "give me the data at the location stored in "p". When p is a null pointer, the location stored in "p" is "nowhere", you're saying "give me the data at the location 'nowhere'". Obviously it can't do this, so it throws a NULL pointer exception.

2. Class Cast Exception:

  • Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance.
  • Casting to the wrong type on findViewById() when getting references to the UI widgets
  • when a program attempts to cast an object to a type with which it is not compatible. (e.g. when we try to use a linear layout which is declared as a relative layout in xml layout and vice versa).
  • Cast the String "1" to an int=no problem but,Cast the String "abc" to an int=raises a ClassCastException

3. Stack Over flow Exception:

  • It can occur in correctly written (but deeply recursive) programs. (Java and android)
  • when a program becomes infinitely recursive.
  • we create layout (deep and complex) that exceeds that stack of platform or virtual machine . recursive or too much of layout will create Stack overflow exception in Android also 
    Too many inner layouts could be the reason.

4. Activity Not Found Exception:

  • The activity is not declared in manifest or Forgetting to register new activities in the manifest.
  • when you call activity and it is not present in package.

5. Android Security Exception:

  • Reading data from storage and doesn't add permissions in Manifest.
  • You need to declare all permissions in the application Manifest that your application uses (Internet, access to contact, GPS, WIFI state,write to SDCard, etc).

6. Out Of Memory Exception OR Monster Exception:

  • bitmap size exceeds VM budget.
  • when a request for memory is made that can not be satisfied using the available platform resources . mainly using high resolution images, bitmap, gallery etc.

7. Application Not Responding (ANR):

  • Mainly comes when you are making network function,or some long process.this will block UI Thread so user can not do any work. to avoid ANR.

8. Original Thread That Created A View Hierarchy Can Touch Its Views:

  • You must have tried to update a view content from another thread than the UI thread. So either create a handler in your UI thread and post your Runnable to this handler OR use the method runOnUIThread to run the lines of code that are doing the update.
9. R.layout.main Cannot Be Found/Missing:
  • R refers to the resource file. In your source code check if you did not import android.R. An android.R import will prevent Eclipse from finding your R file. Also you can check the spelling of the xml layout file name (Here in ‘R.layout.main’, main is the layout file name) , make sure that the xml file name should not contain any space.
10. INSTALL_FAILED_INSUFFICIENT_STORAGE:
  • when installing an application on emulator and emulator doesn't have storage to install application.By default Android virtual device(AVD) provides only 64M for the memory space for Android applications. You can clean your installed application by re-starting the emulator and selecting the Wipe user data flag may solve this.Also you can set the data partition size by launching AVD Manager, then if you press edit on the AVD, you can set the SD Card size.
So I mentioned some common errors we face while developing Android Applications that generally causes force close, so I hope that you will take care of these exceptions while developing Android applications.So try to use try - catch block in all places of program. Don't leave your catch block empty as this can hide errors:

 try{
    // try something
  } catch (Exception e) {
      Log.e("TAG", "Exception in try catch", e);
      return false;
  }
  return true;

I think many of us have faced these exceptions,want to listen from you,have you ever faced these exceptions? 

Wednesday, 4 September 2013

1.description:


A cache that uses a bounded amount of space on a filesystem. Each cache entry has a string key and a fixed number of values. Each key must match the regex [a-z0-9_-]{1,64}. Values are byte sequences, accessible as streams or files. Each value must be between 0 and Integer.MAX_VALUE bytes in length.The cache stores its data in a directory on the filesystem. This directory must be exclusive to the cache; the cache may delete or overwrite files from its directory. It is an error for multiple processes to use the same cache directory at the same time.This cache limits the number of bytes that it will store on the filesystem. When the number of stored bytes exceeds the limit, the cache will remove entries in the background until the limit is satisfied. The limit is not strict: the cache may temporarily exceed it while waiting for files to be deleted. The limit does not include filesystem overhead or the cache journal so space-sensitive applications should set a conservative limit.Clients call edit to create or update the values of an entry. An entry may have only one editor at one time; if a value is not available to be edited then edit will return null.
  • When an entry is being created it is necessary to supply a full set of values; the empty value should be used as a placeholder if necessary. 
  • When an entry is being edited, it is not necessary to supply data for every value; values default to their previous value.
Every edit call must be matched by a call to Editor.commit or Editor.abort. Committing is atomic: a read observes the full set of values as they were before or after the commit, but never a mix of values.Clients call get to read a snapshot of an entry. The read will observe the value at the time that get was called. Updates and removals after the call do not impact ongoing reads.This class is tolerant of some I/O errors. If files are missing from the filesystem, the corresponding entries will be dropped from the cache. If an error occurs while writing a cache value, the edit will fail silently. Callers should handle other problems by catching IOException and responding appropriately.

  2. code:

I create a class named DiskLruImageCache with a DiskLruCache (the one from Jake Wharton) object and the same methods in the simple implementation on the dev guide (displaying bitmaps efficiently):
public class DiskLruImageCache {

    private DiskLruCache mDiskCache;
    private CompressFormat mCompressFormat = CompressFormat.JPEG;
    private int mCompressQuality = 70;
    private static final int APP_VERSION = 1;
    private static final int VALUE_COUNT = 1;
    private static final String TAG = "DiskLruImageCache";

    public DiskLruImageCache( Context context,String uniqueName, int diskCacheSize,
        CompressFormat compressFormat, int quality ) {
        try {
                final File diskCacheDir = getDiskCacheDir(context, uniqueName );
                mDiskCache = DiskLruCache.open( diskCacheDir, APP_VERSION, VALUE_COUNT, diskCacheSize );
                mCompressFormat = compressFormat;
                mCompressQuality = quality;
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

    private boolean writeBitmapToFile( Bitmap bitmap, DiskLruCache.Editor editor )
        throws IOException, FileNotFoundException {
        OutputStream out = null;
        try {
            out = new BufferedOutputStream( editor.newOutputStream( 0 ), Utils.IO_BUFFER_SIZE );
            return bitmap.compress( mCompressFormat, mCompressQuality, out );
        } finally {
            if ( out != null ) {
                out.close();
            }
        }
    }

    private File getDiskCacheDir(Context context, String uniqueName) {

    // Check if media is mounted or storage is built-in, if so, try and use external cache dir
    // otherwise use internal cache dir
        final String cachePath =
            Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
                    !Utils.isExternalStorageRemovable() ?
                    Utils.getExternalCacheDir(context).getPath() :
                    context.getCacheDir().getPath();

        return new File(cachePath + File.separator + uniqueName);
    }

    public void put( String key, Bitmap data ) {

        DiskLruCache.Editor editor = null;
        try {
            editor = mDiskCache.edit( key );
            if ( editor == null ) {
                return;
            }

            if( writeBitmapToFile( data, editor ) ) {               
                mDiskCache.flush();
                editor.commit();
                if ( BuildConfig.DEBUG ) {
                   Log.d( "cache_test_DISK_", "image put on disk cache " + key );
                }
            } else {
                editor.abort();
                if ( BuildConfig.DEBUG ) {
                    Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
                }
            }   
        } catch (IOException e) {
            if ( BuildConfig.DEBUG ) {
                Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
            }
            try {
                if ( editor != null ) {
                    editor.abort();
                }
            } catch (IOException ignored) {
            }           
        }

    }

    public Bitmap getBitmap( String key ) {

        Bitmap bitmap = null;
        DiskLruCache.Snapshot snapshot = null;
        try {

            snapshot = mDiskCache.get( key );
            if ( snapshot == null ) {
                return null;
            }
            final InputStream in = snapshot.getInputStream( 0 );
            if ( in != null ) {
                final BufferedInputStream buffIn = 
                new BufferedInputStream( in, Utils.IO_BUFFER_SIZE );
                bitmap = BitmapFactory.decodeStream( buffIn );              
            }   
        } catch ( IOException e ) {
            e.printStackTrace();
        } finally {
            if ( snapshot != null ) {
                snapshot.close();
            }
        }

        if ( BuildConfig.DEBUG ) {
            Log.d( "cache_test_DISK_", bitmap == null ? "" : "image read from disk " + key);
        }

        return bitmap;

    }

    public boolean containsKey( String key ) {

        boolean contained = false;
        DiskLruCache.Snapshot snapshot = null;
        try {
            snapshot = mDiskCache.get( key );
            contained = snapshot != null;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if ( snapshot != null ) {
                snapshot.close();
            }
        }

        return contained;

    }

    public void clearCache() {
        if ( BuildConfig.DEBUG ) {
            Log.d( "cache_test_DISK_", "disk cache CLEARED");
        }
        try {
            mDiskCache.delete();
        } catch ( IOException e ) {
            e.printStackTrace();
        }
    }

    public File getCacheFolder() {
        return mDiskCache.getDirectory();
    }

}

Utils source code is:

public class Utils {
    public static final int IO_BUFFER_SIZE = 8 * 1024;

    private Utils() {};

    public static boolean isExternalStorageRemovable() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            return Environment.isExternalStorageRemovable();
        }
        return true;
    }

    public static File getExternalCacheDir(Context context) {
        if (hasExternalCacheDir()) {
            return context.getExternalCacheDir();
        }

        // Before Froyo we need to construct the external cache dir ourselves
        final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
        return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
    }

    public static boolean hasExternalCacheDir() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
    }

}

 3. note that:
  • you can visit these links for better understanding and deep information.

  1. android Developers guide
  2. code.google.com
Remember to add permission in your AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

I used this approach by reading this code and the javadoc from Jake Wharton's  DiskLruCache and special thanks to platonius for this code reference.

  4. conclusion:

  • know how to release resources using Disk LRU Cache.
  • know how to avoid out of memory Error  using Disk LRU Cache.


 5. about the post:
  •  The code is not easy to understand,not for me also but may be it will help others to solve their problems.
  •  Don’t mind to write a comment whatever you like to ask, to know,to suggest or recommend.
  •  Hope you enjoy it!

Cheers,

Hamad Ali Shaikh

Tuesday, 3 September 2013

1.description:


LRUCache is a caching strategy where we use Least Recently Used (LRU) eviction policy when the cache is full and we want to add more new data to the cache. LRU cache is used in many caching applications. For example memcached uses LRU cache.

LRUCache cache was introduced in API level 12 (3.1) but is available through the Support Library back to 1.6. It is a generic class which we can strongly type when subclassing it
  2. code:

public class LruMemoryCache extends LruCache<String, Bitmap> 
{
    private final Context context;
     
    public LruMemoryCache(Context context)
    {
        super( 10 );
        this.context = context;
    }
 
    @Override
    protected Bitmap create( String key )
    {
        return Utils.loadAsset( context, key );
    }
}


We’ve defined a cache which will use String keys to index Bitmap objects, much the same as we did in the previous part of this series. The implementation is actually pretty straightforward: In the constructor we call the constructor of the base class to set the size of our cache to 10 items; and we override create which calls the utility method that we defined in part 2.
Using this cache is even simpler still. We first create an instance of our cache:

 
lruMemCache = new LruMemoryCache( getApplicationContext());


and then obtain items using the get() method:

Bitmap bitmap = lruMemCache.get( ASSET_NAME );

So, how does it work? LruCache maintains a list of cached items. Whenever we try and access a specific item, it tries to find it in the cache. If the item already exists, it is moved to the head of the list, and returned. If the item does not exist, then our create() method is called to create a new instance, and this is added to the head of the list before being returned. As a new item is added to the list LruCache checks whether the addition would cause the list to exceed the size that we declared earlier. If not, then it simply adds it, but if so it first deletes the item at the tail of the list. Thus we now have a cache which is not controlled by garbage collection, and which is optimised to keep the frequently accessed items in the cache.

So, how we’ve got some pretty useful functionality in just a few lines of code, but LruCache gives us more. Images can be tricky beasts because they vary in size quite significantly. Holding an arbitrary quantity of images can result in the total size of the cache varying quite enormously depending on the sizes of the individual images. So what if we want to limit the memory usage of our cache? LruCache allows us to override the way that the cache size is calculated. We do this by first changing how the size of each cached item is calculated:
@Override
protected int sizeOf( String key, Bitmap value )
{
    return value.getByteCount();
}

The default implementation of sizeOf() simply returns 1, so this provides the default behaviour that we have already seen with a satic number of items. We have overridden this to return the size of the bitmap instead.
Next we need to change how we specify the size of our cache by changing the constructor:



public LruMemoryCache(Context context)
{
    super( 5 * 1024 * 1024 );
    this.context = context;
}

Here we are specifying a maximum cache size of 5MiB. Whenever the cache exceeds this, items will be evicted from the tail until the size drops below 5MiB once again. We can actually do whatever we want provided that we match the units that we’re using in the constructor to specify the maximum size, to those used in our sizeOf.
This is a much better cache implementation. It gives us greater control and cached items will potentially last much longer than the next GC.
Remember to clear your cache if memory is running low. If onLowMemory() is called on your Activity, it is much better to call evictAll() on your cache and allow it to be rebuilt than it is for your app to crash with an OutOfMemoryError!
LruCache can also be used to manage a cache on the SD card. Rather than storing bitmaps in the cache, you can store File objects instead, calculate the size usingfile.length(), and override entryRemoved() in LruCache to delete the physical file on the SD card when its File is evicted from the cache.
That completes our look at caching. Hopefully you will have a better understanding of some of the tools available to help you to select the correct approach to meet your caching requirements.


3.note that:
    you can visit these links for better understanding and deep information.

4.conclusion:
  • know how to release resources using LRU Cache.
  • know how to avoid out of memory Error  using LRU Cache.
5.about the post:
  •  The code seems to explain itself due to comments, and is very easy to understand.
  •  Don’t mind to write a comment whatever you like to ask, to know,to suggest or recommend.
  •  Hope you enjoy it!
Cheers,
Hamad Ali Shaikh

Friday, 30 August 2013

1. description:


One of the common mistakes developers often make is that never take care of Bitmap objects stored in a data structure like List, LinkedList, HashMap.
public class BitmapStorage {
    String mContent;
    ArrayList<Bitmap> mImages;
 
    // constructor to create the objects
    public BitmapStorage(String content, ArrayList<Bitmap> images) {
        mContent = content;
        mImages = images; // references
    }
}

Things seem to be fined IF developers try to release memory of this BitmapStorage object somewhere else. WHAT IF they FORGET? It’s gonna be really a mess, isn’t it?In my opinion, it is much better if providing such a way to handle memory in such a class.


  2. code:



package pete.android.study;
 
import java.util.ArrayList;
 
import android.graphics.Bitmap;
 
public class BitmapStorage {
    String mContent;
    ArrayList<Bitmap> mImages;
 
    // constructor to create the objects
    public BitmapStorage(String content, ArrayList<Bitmap> images) {
        mContent = content;
        mImages = images; // references
    }
 
    // call in order to free memory of Bitmap objects
    public void freeBitmaps() {
        for(Bitmap image: mImages) {
            // also, it's better to check whether it is recycled or not
            if(image != null && !image.isRecycled()) {
                image.recycle();
                image = null; // null reference
            }
        }
    }
 
    // the destructor should also handle the memory in case it still holds memory
    protected void finalize() {
        freeBitmaps();
    }
}

Like this, developers can freely choose to release memory whenever they feel done with theBitmapStorage objects and when they forget to do so, the destructor “finalize()” would handle the rest.
 3. note that:
  • make sure your Bitmap objects don’t link to any other things when recycling; it would be troublesome. Try to create a nice Bitmap objects live well in a life-cycle!
  4. conclusion:
  • Some information about Memory Leaks in Collections( List,LinkedList and HashMap).
  • know how to lease resources.
  • know how to avoid out of memory Error  in Collections( List,LinkedList and HashMap).
  5. about the post:
  • The next coming post will be on LRU cache and its usage. 
  •  The code seems to explain itself due to comments, and is very easy to understand.
  •  Don’t mind to write a comment whatever you like to ask, to know,to suggest or recommend.
  •  Hope you enjoy it!
Cheers,
Hamad Ali Shaikh

Thursday, 29 August 2013

1.description:
An android app has some limitations when it comes to memory availability. Unlike a normal Java app, you do not have luxury of expanding memory your application uses, as it will be completely dependent on the device on which the app is running, memory available in the phone, number of applications running simultaneously. We will not have control over these external factors so we will need to optimize memory usage on our end.

· Use of flags: Set android:hardwareAccelerated=”true” and android:largeHeap=”true” flags in manifest file. Downside is that these flags are only available after android 3.0. More than 50% of android devices still run on gingerbread (2.3+), so this is not a very reliable solution if you are targeting a larger audience. Though worth a try for high end (3.0+) devices.
·   Memory leakage: DVM garbage collection works n principle of JVM garbage collection, that is it will reclaim the memory for an object if there is no reference to it. So make sure when you are done with an object and do not need it anymore, mark the object reference as null.
·         Use minimum space for an object: Design your classes intelligently, for example if you are handling student data and you address details will not be used frequently, create a separate class and initialize the object only when it is required. Remember, if a char can work, don;t use int or long.
·  Objects are always placed on heap: One of my colleagues was wondering that how can an object occupy space, after the method exits, if the object is declared inside a method. Remember, only references are stored in the stack for method, the actual object is always stored in the heap. So the memory will be freed only when next cycle of garbage collection occurs
·      Use Garbage collection: You can call system.gc(); to initiate garbage collection, but this only suggests JVM/DVM to run a garbage collection, you cannot force it.
·         Playing with Bitmaps/ Images: Bitmaps and images take highest amount of memory, so make sure you recycle() bitmaps as soon as you are done using it. Make sure you have removed all references (imageviews/ objects) to bitmap before calling recycle().
·      Handle Activity Stack: If the app can be used back and forth multiple times, it is better to handle the back-front flow in the code, as default back button handling in android needs to keep a tack of activity stack and uses memory for that. Simplest will be to call previous activity on back button through code and always finish current activity before moving to next.

2.code:

Bitmap bmp =( yourbitmap);
if(bmp != null) {
//release reference
bmp.recycle();
bmp = null;
}

3.note that:
  • Remember to always free Bitmap objects memory before finishing your application or whatever objects containers.
  • Read more about Recycle().

4.conclusion:
  • Some information about Memory Leaks.
  • know how to lease resources.
  • know how to avoid out of memory Error.
  • know how to aquire large heap for application.
  • know what is garbage collection and what is garbage collector.
5.about the post:
  • The next coming posts will be on how to realse memory of bitmap objects stored in List, LinkedList, HashMap and what is LRU cache and its usage. 
  •  The code seems to explain itself due to comments, and is very easy to understand.
  •  Don’t mind to write a comment whatever you like to ask, to know,to suggest or recommend.
  •  Hope you enjoy it!
Cheers,
Hamad Ali Shaikh