Monday, 16 July 2012

Android Fundamental's

Basic Fundamental's of Android

The fundamental building blocks / components of Android are:


1. Activities

2. Services

3. Broadcast Receivers

4. Content Providers.


The means of communication between the above mentioned components is through 


1. Intents

2. Intent Filters


The User Interface elements are by using what are called:


1. Views

2. Notifications

Now, having broadly classified the basics, I would like to give a simple definition for each of them, before we can appreciate the need for each of them.

Activity is the basic building block of every visible android application. It provides the means to render a UI. Every screen in an application is an activity by itself. Though they work together to present an application sequence, each activity is an independent entity.

Service is another building block of android applications which does not provide a UI. It is a program that can run in the background for an indefinite period.

Broadcast Receiver is yet another type of component that can receive and respond to any broadcast announcements. 

Content Providers are a separate league of components that expose a specific set of data to applications.

While the understanding and knowledge of these four components is good enough to start development, the knowledge of the means of communication between the components is also essential. The platform designers have introduced a new conpect of communication through intents and intent filters.

Intents are messages that are passed between components. So, is it equivalent to parameters passed to API calls? Yes, it is close to that. However, the fundamental differences between API calls and intents' way of invoking components is

1. API calls are synchronous while intent-based invocation is asynchronous (mostly)
2. API calls are bound at compile time while intent-based calls are run-time bound (mostly)

It is these two differences that take Android platform to a different league. 

There are 2 types of intents:

1. Explicit Intent

2. Implicit Intent

In an Explicit intent, you actually specify the activity that is required to respond to the intent. In other words, you explicitly designate the target component. This is typically used for application internal messages.

In an Implicit intent (the main power of the android design), you just declare an intent and leave it to the platform to find an activity that can respond to the intent. Here, you do not declare the target component and hence is typically used for activating components of other applications seamlessly

Note: Here for simplicity sake I tell an activity responds to an intent, it could as well be other types of components.
Now I will jump into the example which you can download from here:
This example has 2 activities:

1. InvokingActivity

2. InvokedActivity

The InvokingActivity has a button "Invoke Next Activity" which when clicked explicitly calls the "InvokedActivity" class.
The relevant part of the code is here:

        Button invokingButton = (Button)findViewById(R.id.invokebutton);
        invokingButton.setOnClickListener(new OnClickListener() {
        
         public void onClick(View v) {
         Intent explicitIntent = new Intent(InvokingActivity.this,InvokedActivity.class);
         startActivity(explicitIntent);
         }
        });

As explained in part 1 of the series, this is very much like an API call with compile time binding.


NOTE: The layout for InvokingActivity is defined in main.xml and for InvokedActivity in InvokedActivity.xml. The downloadable example can be opened in Eclipse Ganymede as an android project and can be executed.

Now, we will move on to a more interesting concept of Implicit Intents and Intent Filters. 

This requires a little of theoretical understanding before we move on to an example. 

As described earlier, an implicit intent does not name a target component that should act upon the intent. I 
also said that the android platform resolves as to which component is best suited to respond to an Implicit Intent. How does this happen?

Basically, an Intent object has the following information (among other things like Component name, extras and flags) which is of interest for implicit intents:

  • Action 
  • Category 
  • Data 
So, the android platform compares these 3 (action, category and data) to something called "Intent Filters" that are declared by probable target components who are willing to accept Implicit Intent calls.
i.e. Intent Filters are the way of any component to advertise its own capabilities to the Android system. This is done declaratively in the AndroidManifest.xml file.

So here are some important points to remember:
  1. Implicit Intents do not specify a target component 
  2. Components willing to receive implicit intents have to declare their ability to handle a specific intent by declaring intent filters 
  3. A component can declare any number of Intent Filters 
  4. There can be more than one component that declares the same Intent Filters and hence can respond to the same implicit intent. In that case the user is presented both the component options and he can choose which one he wants to continue with 
  5. You can set priorities for the intent filters to ensure the order of responses. 
There are 3 tests conducted in order to match an intent with intent filters:

  1. Action Test 
  2. Category Test 
  3. Data Test 
For more details about them, you may visit the Android developer documentation here.

Finally we shall look at declaring an implicit intent in one activity which will invoke one of the native activities of the platform by matching the intent filters declared by the same.

The complete code for a very simple implicit intent example that has been described in this article is available for download here.

The InvokeImplicitIntent Activity creates an implicit intent object "contacts". This intent object's component is not set. However, the action is set to "android.content.intent.ACTION_VIEW" and the data's URI is set to "People.CONTENT_URI". 

Such an intent matches with the intent filter declared by the view contacts native activity.
So, when you run this application, it displays the native UI for viewing the existing contacts on the phone.


Here is the relevant piece of code for the same:

           Button viewContacts = (Button)findViewById(R.id.ViewContacts);
        
            viewContacts.setOnClickListener(new OnClickListener() {
            
             public void onClick(View v) {
              Intent contacts = new Intent();
              contacts.setAction(android.content.Intent.ACTION_VIEW);
              contacts.setData(People.CONTENT_URI);
              startActivity(contacts);
             }
            });

In this manner many of the native applications can be seamlessly invoked as one of the activities in our applications through implicit intents.

---------------------------------------------------------------------------------------------------------

The above example uses Android SDK 1.5.
From SDK 1.6 and above, the Contact.People class has been deprecated and we need to use the ContactsContract class. So the line in code

       contacts.setData(People.CONTENT_URI);

has to be replaced by 

       contacts.setData(ContactsContract.Contacts.CONTENT_URI);
Here is the complete source code that has been tested with Android SDK 2.1 

No comments:

Post a Comment