Android: Nuts and Bolts VI

Today we’re going to do some fun Activities together! Perhaps it would be more fair to say that we’re going to have fun learning about Activities. In Android! In this article, I will explain the Activity model, how to use it, and tell you why I like it. Interested? Check behind the Read More!

 

The Activity model in Android is a pretty fascinating concept; it is essentially outlined with user experience in mind from the beginning. An Activity is exactly what it sounds like, it is an ‘action’ that a user can ‘do’. This could be browsing the web, looking at the results of a computation, requesting a computation, writing contact information into a form, or just about any other cell phone ‘verb’ you could think of. Within an application, Activites split up various ‘screens’; rather than destroying a user interface and repainting new elements, we simply launch a new Activity! From a programming standpoint, these are each divided up into a separate Class.

Activities are also relevant between applications; that is, an application can be programmed to call another application to perform a task. Examples of this would be the Camera app calling the SMS or Gmail app to send a picture. This is accomplished through use of Intents which can explicitly or implicitly request that another Activity be launched. Implicit Intents allow us to do cool things like implement ‘Share’ buttons (as in the Camera example), where the app will ask a user what they want to do with a given piece of data. I feel that the ‘Intent’ terminology is excellent, as is Activity, because they really describe what it is that the user is doing. This also creates a very user-centric feel to the programming environment, which is nice because developers often don’t think enough about the end user and their experience.

The easier part of this model to tackle code-wise, in my opinion, are simple Activity-to-Activity switches within one application. This technically invokes Intents as well, but is less involved because it doesn’t need special Intent-Filter tinkering. Essentially, you declare an Intent variable, giving it the name of your second (new) Activity’s .class file. You can optionally create a bundle and perform a putExtras to pass along a number of variables into the new Activity. This allows us to create form-style activities to request information from a user, and then pass that information back to another part of the application.

Once that is done, we either startActivityForResult, or we just startActivity. If you plan on returning information back to the Activity you are launching from, you use the result version. If you are making a one-time leap from one thing to another, you just start the Activity. Note that either way, you can still pass variables to the new Activity – the only difference is whether you expect anything back.

 Intent i = new Intent(this, NameOfActivityToLaunch.class);
Bundle bundle = new Bundle();            
bundle.putInt("String1 that you can remember later", someIntegerValue);
bundle.putString("String2 that you can remember later", someStringValue);
i.putExtras(bundle);
startActivityForResult(i, SOME_ACTIVITY_IDENTIFIER_CONSTANT_1);
// OR, alternatively, you can use:
// startActivity(i);

assuming that we performed a startActivityForResult, we need to add an additional method to the Activity we launched from:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Bundle extras = intent.getExtras();
switch(requestCode){
case SOME_ACTIVITY_IDENTIFIER_CONSTANT_1:
//get variables from the Activity you launched and do stuff with them.
Integer tmp = extras.getInt("String you wrote in the activity you launched");
break;
case SOME_ACTIVITY_IDENTIFIER_CONSTANT_2
//do different stuff for a second activity
break;
}
}

Now, that covers everything inside of your original Activity, but what about the one you’re launching? How did we read the variables we sent to ourselves? How did we write variables back to ourselves for when the Activity returns? Easy! (as you might expect, it is the same). In our onCreate for the new Activity, we:

if(getIntent().getExtras() != null){
Bundle extras = getIntent().getExtras();
String ourStringFromBefore = extras.getString("String2 that you can remember later");
Integer ourIntegerFromBefore = extras.getInt("String1 that you can remember later");
}

and we can write stuff back and return to our original Activity by:

Bundle exitBundle = new Bundle();            
exitBundle.putInt("String you wrote in the activity you launched", someIntValueWeCalculated);
Intent mIntent = new Intent();
mIntent.putExtras(exitBundle);
setResult(RESULT_OK, mIntent);
finish();

and Android magically knows that we want to go back to our original activity when we finish(); cool huh?

One thing I’m fond of doing is setting Dialog as my theme for an Activity in my Manifest file for short, information query activities:

[activity android:name=".EditName" android:theme="@android:style/Theme.Dialog" android:label="@string/name_dialog_name"][/activity]
(NOTE: I don't really mean [ and ] here, I mean LESS_THAN and GREATER_THAN, but the website's html/xml thinks I'm
trying to talk to it when I use those characters.)

Which allows me to fully customize a dialog form for the user to give me information, as opposed to using the pre-existing Dialog popups that Android provides (Note: the pre-existing Dialogs are actually very good and you should use them instead where you don’t need customization). In this example I built an EditName class with a specific layout that I wanted, and returned the values entered by the user to my original Activity.

Next time around I’ll cover the cross-application Activity switches, and how to do Intent-filters!