Monday, June 30, 2014

Check for Memory leaks and management in Android


There are two ways to manage memory first is Automatic memory management and second is Manual memory management.

Lets first start with Garbage collection which is a form of automatic memory management. The garbage collector or just collector attempts to reclaim garbage or memory occupied by the objects that are no longer in use by the program. Now lets see how GC works.

Every object tree must have one or more root objects. As long as application can reach those roots, the whole tree is reachable. But when are those root objects considered reachable? Special objects called Garbage-collection roots are always reachable and so is any object that has a garbage collection root at its own root.



There are mainly three kinds of GC roots :
  • Main Thread
  • Local variables in main thread
  • Static variables


To determine which object is no longer in use, the DVM intermittently runs what is very aptly called mark-and-sweep algorithmIt's a straight forward two way process:
  1. The algorithm traverses all object references, starting with GC roots, and marks every object found as alive.
  2. All of the heap memory that is not occupied by marked objects is reclaimed. 
Garbage collection is intended to remove the cause for classic memory leaks :  unreachable-but-not-deleted objects in memory. However, this only works for memory leaks in the original sense. Its possible to have unused objects that are still reachable by the application because developer simply forgot to dereference them. Such objects cannot be garbage-collected.

So, garbage collection is done intermittently by VM which can be checked in logs GC_XXXXX, which shows how much memory is been cleared. 
Note: Increasing heap for app is dangerous as then GC will take more time to traverse through the whole object tree and hence will effect performance.

Analyzing memory leaks

  • Memory leaks can be easily analyzed first by looking at log files GC_XXX/XXX... The first number after free shows how much size of objects are being used. Try doing something and observe if it varies and is huge for long time, then there is a memory leak.
  • MAT(Memory Analyzer tool) : Download MAT for eclipse, click on required process under DDMS and click Dump HPROF file, it will be downloaded, but to open it in MAT it needs to be converted. Go to sdk>tools and type this command ./hprof-conv test.hprof mat.hprof for ubuntu and open this converted file in MAT by simply clicking on open heap dump.
          There are two types of objects in heap
    • Shallow heap : just the node in tree which has its own size.
    • Retained heap : when removed from heap, it will actually remove other connected nodes.
  • How to use MAT
    • Open Dominator_tree at the bottom of Pie chart, it will show the objects taking max retained heap.
      • Right click on that object>Path to GC roots>Exclude weak references.
      • It will traverse to exact class.
    • Open Histogram at the bottom, this shows number of instances per class.
      • Right click on that object>Show object by class>by incoming references.
      • Then to GC roots and it will traverse to exact class.
      • Also here we have a small search bar, where we can see instances of our class, just type MainActivity and see. If it is more then one, then there is a leak.






Sunday, June 22, 2014

Best practices for better performance in Android



  • Avoid runtime scaling of Bitmap

Background drawable always fits images, so it basically auto scales to fit and runtime scaling is very expensive, it effects performance. As it uses bifiltering technique to scale which is expensive but gives good scaled image.
Always prescale bitmap to increase performance, performance difference is 50% increase.
OriginalImage = Bitmap.CreateScaledBitmap(originalImage,
                                                view.getWidth(), //new width
                                                view,getHeight(), //new height
                                                true // bilinearfiltering);

  •  Use invalidate() for required portion only

invalidate() though looks simple but comes with big cost as it actually refreshes the whole screen.
So instead use, this will only refresh the required area and performance will increase upto 50%
invalidate(Rect);
invalidate(left, top, right, bottom);

  • Use Hierarchy View tool - view hierarchy is directly proportional to performance

 When clicked on view load hierarchy, it will show the the whole view hierarchy used in the focused window.
    • The less the view, good will be performance.
    • It also shows time taken to measure layout and draw views in miliseconds.
    • Try to look for layout which has only one child and get rid of that.


For example, Instead of using a layout with a textview and image just use textview with drawableleft

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/hello”
android:drawableleft=”@drawable/icon”
/>

  • Use ViewStub where ever views are mostly invisible or gone state
 A ViewStub is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime. When a ViewStub is made visible, or wheninflate() is invoked, the layout resource is inflated. The ViewStub then replaces itself in its parent with the inflated View or Views. Therefore, the ViewStub exists in the view hierarchy until setVisibility(int) or inflate() is invoked. The inflated View is added to the ViewStub's parent with the ViewStub's layout parameters. Similarly, you can define/override the inflate View's id by using the ViewStub's inflatedId property. For instance:


     <ViewStub android:id="@+id/stub"
                                android:inflatedId="@+id/subTree"
                                android:layout="@layout/mySubTree"
                                android:layout_width="120dip"
              android:layout_height="40dip" />



  • Use <merge/> tag to avoid unnecessary  declaration of layout for single child
 The <merge /> tag helps eliminate redundant view groups in your view hierarchy when including one layout within another. For example, if your main layout is a vertical LinearLayout in which two consecutive views can be re-used in multiple layouts, then the re-usable layout in which you place the two views requires its own root view. However, using another LinearLayout as the root for the re-usable layout would result in a verticalLinearLayout inside a vertical LinearLayout. The nested LinearLayout serves no real purpose other than to slow down your UI performance.

To avoid including such a redundant view group, you can instead use the <merge> element as the root view for the re-usable layout. For example:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add"/>
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/delete"/>
</merge>

Now, when you include this layout in another layout (using the <include/> tag), the system ignores the<merge> element and places the two buttons directly in the layout, in place of the <include/> tag.

  • Use optimized data containers
Use SparseArray instead of hash maps as for maps where keys are of type integer, it’s typically more efficient to use the Android SparseArray API

The main interest of the SparseArray is that it saves memory by using primitives instead of objects as the key.

  • Use services sparingly and properly

If your app needs a service to perform work in the background, do not keep it running unless it's active and doing some task . The best way to limit the lifespan of your service is to use an IntentService, which finishes itself as soon as it's done handling the intent that started it.

  • Release memory when your user interface becomes hidden and memory is running low

When the user navigates to a different app and your UI is no longer visible, you should release any resources that are used by only your UI. Releasing UI resources at this time can significantly increase the system's capacity for cached processes, which has a direct impact on the quality of the user experience.
To be notified when the user exits your UI, implement the onTrimMemory() callback in your Activity classes. You should use this method to listen for the TRIM_MEMORY_UI_HIDDEN level, which indicates your UI is now hidden from view and you should free resources that only your UI uses.

During any stage of your app's lifecycle, the onTrimMemory() callback also tells you when the overall device memory is getting low. You should respond by further releasing resources based on the following memory levels delivered by onTrimMemory():

 Implement ComponentCallbacks2, override onTrimMemory(int level) and level can be checked for different inbuilt values like   TRIM_MEMORY_UI_HIDDEN or  TRIM_MEMORY_RUNNING_LOW 

  • Memory and heap management
Heap allocation for app is different for different hardware. Like for initial phone G1 was 16 MB and Motorola zoom has 48 MB.

To get an estimate of your app available heap in megabytes use

ActivityManager.getMemoryClass();

Generally if you think you app requires extra heap then in honeycomb new attribute was added to take large heap for a particular app. But this should be avoided unless really required, as large heap means large garbage collection, which intern will effect on performance.

In manifest.xml under <application
                                                                android:largeHeap = “true”
                                                />
ActivityManager.getLargeMemoryClass().

  • Use parcelable where necessary instead of Serializable
There are two ways to pass object references to activities and fragments

 Serialization is a marker interface, which implies the user cannot marshal the data according to their requirements. In Serialization, a marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java objects member and behavior, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in comparison to Parcelable.   



DDMS - Dalvik Debug Monitor Server

            Android ships with a debugging tool called the Dalvik Debug Monitor Server (DDMS), which provides port-forwarding services, screen capture on the device, thread and heap information on the device, logcat, process, and radio state information, incoming call and SMS spoofing, location data spoofing, and more. 

Below I have explained how to use few of the most useful services in DDMS 


  • Viewing heap usage for a process

    • DDMS allows you to view how much heap memory a process is using. This information is useful in tracking heap usage at a certain point of time during the execution of your application.
    •  To view heap usage for a process:
    •  In the Devices tab, select the process that you want to see the heap information for.
    •  Click the Update Heap button to enable heap information for the process.
    •  In the Heap tab, click Cause GC to invoke garbage collection, which enables the collection of heap data. When the operation completes, you will see a group of object types and the memory that has been allocated for each type. You can clickCause GC again to refresh the data.
    • Click on an object type in the list to see a bar graph that shows the number of objects allocated for a particular memory size in bytes.


  • Tracking memory allocation of objects
DDMS provides a feature to track objects that are being allocated to memory and to see which classes and threads are allocating the objects. This allows you to track, in real time, where objects are being allocated when you perform certain actions in your application.

    •    To track memory allocation of objects:
    •  In the Devices tab, select the process that you want to enable allocation tracking for.
    • In the Allocation Tracker tab, click the Start Tracking button to begin allocation tracking. At this point, anything you do in your application will be tracked.
    • Click Get Allocations to see a list of objects that have been allocated since you clicked on the Start Tracking button. You can click on Get Allocations again to append to the list new objects that that have been allocated.
    • To stop tracking or to clear the data and start over, click the Stop Tracking button.
    •  Click on a specific row in the list to see more detailed information such as the method and line number of the code that allocated the object.


  • Examining thread information
            The Threads tab in DDMS shows you the currently running threads for a selected process.

    •  In the Devices tab, select the process that you want to examine the threads for.
    •  Click the Update Threads button.
    • In the Threads tab, you can view the thread information for the selected process.


  • Starting method profiling
            Method profiling is a means to track certain metrics about a method, such as number of calls,   execution time, and time spent executing the method.
            To start method profiling:

    •  On the Devices tab, select the process that you want to enable method profiling for.
    • Click the Start Method Profiling button.
    • Interact with your application to start the methods that you want to profile.
    • Click the Stop Method Profiling button. DDMS stops profiling your application and opens Traceview with the method profiling information that was collected between the time you clicked on Start Method Profiling and Stop Method Profiling.


OAuth 2.0 in Android part - 2



Using Tasks API (Account manager)

Using account manager here, device google accounts are shown in dialog box and by selecting one shows grant permission page and then access_token is retrieved. 


Process to use tasks api in your project.


  • Import Google client libraries  google-api-java-client-1.4.1-beta.zip and task specific jar google-api-services-tasks-v1-1.1.0-beta.jar
  • Select the Google Account of the user through Account Manager.
  • Generate API key and set up the Tasks service object
    • Create a project or use an existing one in google console.
    • Enable the Tasks API on your project in google console by toggling the Tasks API switch to ON
    • The API Key can be found at API Access > Simple API Access > API Key
  • Get an OAuth 2.0 access token from the AccountManager for the Task API
  • Make calls to the Tasks API

  1. Below is the flowchart to explain the process in pictorial way to get a better idea.





Through application user is navigated to below screens and asked to grant permission to obtain access token.






OAuth 2.0 in Android part - 1

What is OAuth?

OAuth is an open standard for authorization. OAuth provides client applications a 'secure delegated access' to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner, or end-user. The client then uses the access token to access the protected resources hosted by the resource server. OAuth is commonly used as a way for web surfers to log into third party web sites using their Google, Facebook or Twitter accounts, without worrying about their access credentials being compromised.



There are basically two ways to attain this (using Google service provider)

General OAuth 2.0 workflow


  •  You : the user
  • My application : the consumer
  •  Google : the provider

 When an application wants to access your data using OAuth, it needs to participate in the OAuth workflow. In order to accomplish this flow,  a series of request / responses between the consumer (my application), and the provider (Google) need to be initiated. Each interaction (consumer sending a request and provider sending a response) involves sending / receiving a set of parameters.

We’ll cover the OAuth flow in detail here, including all the steps that both the consumer, provider and user needs to take. The detailed steps are outlined here :
  The consumer registers his domain with the provider (prerequisite).
  The provider accepts the registration and provides a consumer key and a consumer secret.
  The consumer requests a request token (OAuthGetRequestToken).
  The service provider sends the request token.
  The consumer sends his request token for authorization (OAuthAuthorizeToken)
  If the user is not logged into the service provider, he does so now.
  User is authenticated by the provider. The consumer doesn’t capture the username/password
  The provider informs the user that the consumer wants to access his protected resource
  The users needs grants access to the consumer
  The provider then sends an authorized token to the consumer.
  The consumer sends his authorized token (OAuthGetAccessToken)
The service provider knows that the user has granted access and sends an access token

All of these interactions are done through HTTP requests. The provider provides the endpoints for each interaction in the OAuth flow. The consumer takes note of each endpoints, and uses them in the interaction with the provider to finish the OAuth workflow.
Most google services define the following oAuth endpoints :
OAuth Endpoint
URL
Request token endpoint
https://www.google.com/accounts/OAuthGetRequestToken
Authorization endpoint
https://www.google.com/accounts/OAuthAuthorizeToken
Access token endpoint
https://www.google.com/accounts/OAuthGetAccessToken

The consumer will send a request to each of these endpoints. The provider then responds to these requests by sending an appropriate response so that the consumer can continue

In this part will explain OAuth 2.0 using signpost lib

This process  directly takes to google login page and then grant access page and returns back to application with access_token and secret_token. Below is the flowchart to explain the process in pictorial way to get a better idea.


Below are the libraries that would be required

First we need to get the access token, lets create a generic class which will hold all the generic data like scope, url etc..

Add these constants.
public static final String CONSUMER_KEY  = "anonymous";
public static final String CONSUMER_SECRET  = "anonymous";

public static final String SCOPE  = "https://www.google.com/m8/feeds/";
public static final String REQUEST_URL  = "https://www.google.com/accounts/OAuthGetRequestToken";
public static final String ACCESS_URL  = "https://www.google.com/accounts/OAuthGetAccessToken";  
public static final String AUTHORIZE_URL = "https://www.google.com/accounts/OAuthAuthorizeToken";
 
public static final String GET_CONTACTS_FROM_GOOGLE_REQUEST = "https://www.google.com/m8/feeds/contacts/default/full?alt=json";
 
public static final String ENCODING  = "UTF-8";
 
public static final String OAUTH_CALLBACK_SCHEME = "oauth-example";
public static final String OAUTH_CALLBACK_HOST = "callback";
public static final String OAUTH_CALLBACK_URL = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;
public static final String APP_NAME             = "OAuthExample";


Now initialize consumer and provider and make a request to get token.
try {
    consumer = new CommonsHttpOAuthConsumer(C.CONSUMER_KEY, C.CONSUMER_SECRET);
    provider = new CommonsHttpOAuthProvider(C.REQUEST_URL  + "?scope=" + URLEncoder.encode                              (C.SCOPE, C.ENCODING) + "&xoauth_displayname=" + C.APP_NAME,
              C.ACCESS_URL,
              C.AUTHORIZE_URL);
     } catch (Exception e) {
      Log.e(C.TAG, "Error creating consumer / provider",e);
     }
try {
 String url = provider.retrieveRequestToken(consumer, C.OAUTH_CALLBACK_URL);
 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
 this.startActivity(intent);
   
    } catch (Exception e) {
   Log.e(C.TAG, "Error retrieving request token", e);
  }

We need to override onNewIntent(Intent intent) as this method is called once we receive intent, which has request token uri.

@Override
public void onNewIntent(Intent intent) {
  super.onNewIntent(intent); 
  prefs = PreferenceManager.getDefaultSharedPreferences(this);
  final Uri uri = intent.getData();
  if (uri != null && uri.getScheme().equals(C.OAUTH_CALLBACK_SCHEME)) {
   Log.i(C.TAG, "Callback received : " + uri);
   Log.i(C.TAG, "Retrieving Access Token");
   getAccessToken(uri);
  }
 }
Now to retrieve token and token secret from the uri
private void getAccessToken(Uri uri) {
final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
 try {
  provider.retrieveAccessToken(consumer, oauth_verifier);
  final Editor edit = prefs.edit();
  edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken());
  edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret());
  edit.commit();
   
  String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
  String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
   
  consumer.setTokenWithSecret(token, secret);
   
  } catch (Exception e) {
   Log.e(C.TAG, "Access Token Retrieval Error", e);
  }
 }

Through application user is navigated to below screens and asked to grant permission to obtain access token.


To get the contacts just make a call


String jsonOutput = makeSecuredReq(C.GET_CONTACTS_FROM_GOOGLE_REQUEST,getConsumer(this.prefs));