Tuesday, 28 February 2012

error: Obsolete Build.xml Need to delete or regenerate


   A Small Info

   If you are trying to build the project using ant scripts which points to your customized Build.xml . In that case if anyone  getting an "error: Obsolete Build.xml Need to delete or regenerate"  All you have to Do it

  1) Check your ADT version because android changed the ant scripts and there building architecture  tools from ADT 14 onwards  http://tools.android.com/recent/buildchangesinrevision14

  All you have to do his  replace the 'tools' folder in your current SDK with 'tools' folder in a SDK which is less than revision 14

 then go the cmd shell

 -> go to your tools path (always prefer to set as environment variable so that you can access the SDK_PATH easily ,In Linux edit .bashrc in Mac you can create .env text file or in Windows Enviornment path tab)

    from there trigger 'android update project -p <your project path>'
  
   if it asks to set the target ID

  all you have to do is take a back step and trigger "android list targets" from the same tool path it will show the targetID in cmd prompt

 so you can add that  targetID to your update comment

   'android update project -t<ID> -p<project path>' there goes it will automatically update the local.properties file and your build properties

 Then you are in the good shape to build  your project through build.xml .......

 Thanks
 Roger Gasper

Monday, 6 February 2012

Memory Mangement In Java And in Android Tech


Many of the android Developers are get into this night mare OUT OF MEMORY ERROR or Bitmap Exceeds VM Budget
This situation will arise due to following reasons

 1) When you are dealing with large Bitmaps or Images
 2) When you are trying to rotate the device continuously
 3) When you are using unnecessary Object and increasing the heap memory

   Among  three scenarios the first two are culprits third one we can catch it by using some memory profiler tools and able to fix it.
 
  How we can get rid of OOME?First two scenarios are happening quite often

             It is not a mistake from Developer it is bug from Android OS code because the Dalvik Virtual Memory limits the amount of memory that any Android application can use to either 16 or 24MB. And there is no way to change this allocation pro grammatically. Only way is to alter the OS Code and recompile But that is far from our hands as millions of users using the application we cant tell them to recompile the OS to run this application . But the Vendors like Samsung,Motorola or those who are collaborating   with Goggle can make this happen.
   Iphone developers are safe in this area as they have the leverage to release the memory after use since Objective C is providing
 
           Ok Now lets move to the first two points in Detail and the solution which we can do from our side

    1) Dealing with large Bitmaps

                    Now 16MB is enough to run even a complicated game but even though the VM runs out of memory this is because the OS is not releasing the bitmaps objects properly once the program is through with them. The only way the OS will release the memory when the application ends,and even it takes some time So lets see what are the solution to fix this


    a) Reducing the Size of Bitmap
                        This Solution involves scaling the bitmap and reducing the amount of memory usage but this will not solve the problem, it simply minimises its impact. This solution will work out if you are using very few bitmaps or images

    b) Bitmap.recycle()
                        This is good practice  of programming when ever you are trying to deal with the bitmaps call Bitmap.recycle() this will immediately mark a bitmap for garbage collection if you are using collection of bitmaps don't forgot to call individually. But as this will also not giving a concrete solution as Java Garbage Collector is a low priority thread we don't know when it will collect the object. But its a good practice which will solve to an extend

    c) Utilize the Data Structures in Java

                Suppose you are working with some multiple images make sure all bitmaps are in a Data structure so that all bitmaps are properly managed. Because sometimes even one Bitmap is enough to create the issue so whether it is a activity or back end Java class if you are dealing with multiple images there should be a function like this freeBitmapsUsed() and also make sure to override the finalize() method so that we can make sure that it is properly collected by the JVM
                           // call in order to free memory of Bitmap objects
        public void freeBitmapsUsed() {
                    //traverse the data structure
            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();
        }

          Lets move to the Second Scenario

       2) When you are trying to rotate the device continuously
                           These is a serious OOME issue which almost all the developers faced a fast switching between the screen modes portrait/landscape. Why it is happening?
           Its impact will be very high when that UI is constructed through code, or if that UI contains some large bitmaps, or it contains some complex canvas drawings.
            These is a pure memory leak issue which we need to blame ourselves. Keeping in mind that you are Java developer not in a program where you have the span  to deal with memory a lot
                First suggestion  you have to see requirement if that UI can be developed through xml then go for it that is the best practise  because keeping  different xmls in portrait and Landscape folders its  a good android approach because OS itself will take care lot of de allocation no need to worry too much but there are certain circumstances where we need to create the UI through code or even we need to draw through canvas in that case we need to be little bit care. Whenever fast switching between the modes crash will happen.

           It is happening mainly because you are referencing you context ie, your Screen Instance to a long time

            That is when ever you are switching the modes from portrait to landscape and vice versa android is recreating your views it is taking the portrait layouts and resoures everything and literally recreating the view
           So keeping this in mind Whenever a rotation happens we need to make sure there should not be any obstacle in our activity/UI which prevents the garbage collector from collecting that pointer/Screen Instance/ActvityContext
           ie, You should not hold any static reference to Activity context. Playing with activity context needs to be careful at your risk a simple example

                
                    private static Drawable sBackground;
 
@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);
 
  TextView label = new TextView(this);
  label.setText("Leaks are bad");
 
  if (sBackground == null) {
    sBackground = getDrawable(R.drawable.large_bitmap);
  }
  label.setBackgroundDrawable(sBackground);
 
  setContentView(label);
}



                   Its a pure memory leak code ,here you can see that Drawable is statically referenced. But you can see there is no direct reference to activity context. Still when you rotate the phone you can see a memory leak
 that is your drawable sBackground points to label which in turns created from the context new TextView(this); so when ever rotating the device by default GC_CONCURRENT will call which try to deallocate the context  but it cant deallocate this activity instance as one of its child ie, sBackground is statically referenced so what happens when you are continuously switching the mode to quite a long time you will get crash OOM by showing exceeds VM memory budget, ie, 16 or 24MB because your heap memory is increased on every switching

     So make sure your context ie, a pointer which holds the whole complex UI component in fact this screen pointer in android which consumes a lot of your memory so play in safe mode with your activity context don't make any static reference directly or indirectly to this pointer which leaks your memory

     

                You can see here let take right side as portrait and left side as Landscape  the root one is our Activity Context/Screen Pointer  . Your View is created by Lot of View Groups and Child Group if any of your View Group Components or View Child's is statically referenced then you are trapped. The moment when you switch it portrait mode OS recreates the whole View with revised layouts and images then it will try to reallocate the portrait context in that moment if you are making any hinderance through code you will encounter with the issue

     Here another thing you need to notice the root pointer will be the summation of all spaces allocated by the View Components and View Child's then you can imagine its importance these statistics you can be clearly identified when you load a binary .hprof file to MAT tool in eclipse which i specified as last of this article



          I already specified below an example log cat when ever you are on a leaking code when you make orientation in screen you can see in logcat the leaked memory status you can see your heap free statistics decreasing for more info you can see below log cat explanations




         Thanks to Google as i had noticed from Honey Comb onwards they are collecting the bitmap object in right manner as they move this task from GC_EXTERNAL_ALLOC to GC_CONCURRENT you can see that in log cat so there will not be much out of memory issue  due to bitmap from Honey Comb onwards but still the second matter about Context leaking on Screen Orientation is there so we need to take care that

    Best way to analyze this memory leaks are put a tight monitoring on the logcats coming you can see that just put adb logcatt filter by giving the process id in command prompt


    eg: D/dalvikvm(9050): GC_CONCURRENT freed 2049k, 65% free 3751K/9991k, external 4703k/5261k, paused 2ms+2ms

         Just anlayze the message
     First one is reason for Garbage Collection there are 5 reasons when a GC calls

     GC_CONCURRENT :
               It is a collection which will be kicked by the OS itself when they seems that
   the heap is touching the VM budget (16/24mb) and it is a safe collection now after honeycomb they moved bitmaps into this category which is a good sign for developers they will take care its deallocation but keep in mind don't make any static reference to bitmaps allow them to deallocate properly without any hindrance

     GC_FOR_MALLOC:
             This is basically the OS cant able to finish the Concurrent garbage collection in time so that your application needs some memory in that case OS calls GC_FOR_MALLOC which will deallocate some memory from outside your application and make sure it makes the room for you

     GC_EXTERNAL_ALLOC:
     which will not be seen from Honeycomb because in older version they were used this for pixel allocation in Bitmaps which is a problem for developers but now they moved this to GC_CONCURRENT from honeycomb onwards

    GC_HPROG_DUMP_HEAP:
    Which you will see when you trying to dump the heap memory binary data to a .hprof file which is useful i will discuss in last of this article

     GC_EXPLICIT:
       That is developer when explicitly calls to collect that is our System.gc();
   
other message comments are

      freed 2049k: that is you can see amount of memory freed from this collection you can see here 2049k

     
     65% free 3751K/9991k: that is our heap statistics 65% are free now using 3751 out of 9991k

     external 4703k/5261k: that is as i said the memory which they externally allocated for storing the pixel buffers in below Honeycomb version

     paused 2ms+2ms: the time taken to GC to complete its operation if your heap is small it will take less time other wise long time.


     So monitoring the log is a basic way but it is difficult and tedious so what you can do is you have the option in Eclipse tool where you can dump the heap memory and save in your local machine in .hprof format then Download the Eclipse Memory Analyzer (MAT) from http://eclipse.org/mat and load the .hprof file which you saved. There goes you can see the statistics and you can find out the memory leaks everything. And also be handy with ActivityManager.getMemoryClass() which helps at the time of Development.

Thanks
Roger Gasper