Introduction
You have set up an Android development environment on your computer in Setting Up Your Android Development Environment. You have got everything that you need to cook up an Android app. What should your first Android app be? Traditionally, the first program that every programmer writes would be to say "Hello" to the World! You are no exception. What are you waiting for? Let's go to the kitchen (I mean Android Studio).
Hold on a second, note that this article builds on the learning of the preceding ones - i.e. Setting Up Your Android Development Environment and Introduction to Android, you will be reminded to refer to them when needed. Hold on another second, this is a strictly one-way follow-through journey, you are advised not to skip any stations. Let the journey begin...
On the Mark, Get Set, Cook~
Turning On the Light
Launch the Android Studio! A nice loading screen splashed with sihouettes of phones and tablets in various sizes in the background shows up to keep you informed of the progress of loading. (Figure 1)
|
Figure 1: Loading Screen
|
After a while, you will be greeted with the Welcome to Android Studio screen. (Figure 2)
|
Figure 2: Android Studio Welcomes You
|
Getting Ready the Ingredients
Click the New Project... on the welcome screen to start the process of creating a new project. Follow these steps. I suggest you use the parameters in this example first. You can try out different parameters when you become more familiar with the process.
-
Filled out the form that appears in Figure 3:
|
Figure 3: Configure New Project
|
|
Figure 4: Edit Package Name
|
-
Application name is the app name that appears to the users on the Google Play and on their screen.
-
Company Domain is the domain name of your organization or personal website. For this purpose, just let Android Studio decides for you.
-
Package name is a unique namespace for your app that distinguishes it from all other apps installed on the Android system. By default, it usually begins with the reverse company domain name and ends with a period then the Application name minus any spaces. To change the package name, click the Edit text on the left end of Package name field (Figure 4).
-
Project Location is the location on your disk where the project is stored.
Once it is ready, go Next.
-
Select the minimum SDK version for your project as shown in Figure 5:
|
Figure 5: Select Form Factors
|
You help in making better decision on the choice of minimum SDK version, click on Help me choose in Figure 5 and you will be presented with a form showing the distribution of Android devices across API levels in Figure 6.
|
Figure 6: Distribution of Android Devices across API Levels
|
Once it is ready, go Next.
-
Select Blank Activity from a list of pre-defined templates as shown in Figure 7. Scroll to see the different templates provided. These templates automatically create an Activity and the corresponding XML files. You can use these templates to quickly set up a basic Android application, which you can then run on a device or in the emulator.
|
Figure 7: Select a Template
|
Once it is ready, go Next.
-
You have reached the last step of creating new project. Just leave the default parameters as they are. But do not click the Finish button yet! Let's take a look at the three items there:
|
Figure 8: Select Form Factors
|
-
Activity Name is the programmatic name of the UI screen. This will be the initial screen that will be launched when the app is launched. In OO's term, it is a subclass of Activity class and is written in none other than Java.
-
Layout Name is the name of an XML file that defines the layout of all the components in an Activity.
-
Title is the title of the Activity.
Click Finish and proceed.
Putting Them Together
You should see the Android Studio's screen shows up like this one in Figure 9. Your screen's layout may appear somewhat different from mine but that is fine. It is impossible to show a detailed image here, instead look at your own screen.
|
Figure 9: Android Studio's Screen
|
Getting hungry? Wonder how your dish going to turn out? Let's cook and taste it.
Cook it...
Remember the Android Virtual Device (AVD) emulator you have set up in Setting Up Your Android Development Environment. You will emulate your app on this AVD. Follow these steps:
-
On the Android Studio's menu bar, click app > Edit Configurations... as shown in Figure 10. Alternatively, you can click Run > Edit Configurations....
|
Figure 10: Edit Configurations
|
Once it is ready, go Next.
-
You will be presented with a form as shown in Figure 11. Under the Target Device section, Select Emulator > name of your AVD > OK.
|
Figure 11: Select an AVD
|
-
To start cooking, click the green right-pointing triangle beside app icon on the menu bar (Figure 10) or click Run > Run 'app'. After some waiting, out come the AVD! (Figure 12)
Note:
The Android emulator is a great tool, besides its intended use, it is also good for your health, though unintentionally, I swear, hear me out. Android emulator is well-known for its slowness, do not expect it to response immediately after a click, you have got to be very very patient with it. But the wait is worth it as it will do its work as promised, and it forces you to slow down your pace and that is good for your heart. In my previous article, I have recommended that once the emulator is started; leave it running while you do your work.
|
Figure 12: AVD Launched
|
-
Instead of using your finger, use your mouse to swipe and click (touch) on the AVD. Swipe the key lock symbol all the way to the left until it is out of the way to unlock the screen, go to home, flip through the menu, until you find this green robot icon called My First Android App (Figure 13) - that is the app that you have just created and deployed to the AVD. Alternatively, you can manipulate the AVD from your computer keyboard; refer to Mapping between Emulator keys and Keyboard Keys. For example, toggling Ctrl + F11 will emulate the change of screen orientation. Try it!
|
Figure 13: App deployed to AVD
|
-
Ok, the dish is cooked. It is time to taste it. Click the My First Android App icon. Your app exclaims, "Hello World!" (Figure 14). How does it taste?
|
Figure 14: App running on AVD
|
Alright, I must admit that it tasted bland. In fact, what you have just tasted is a default app cooked up by Android Studio - it is more like an instant noodle. You have not done any actual cooking (coding) yet. You will have a chance to spice up your app later on, so be patient. For now, let's rewind and revisit the whole process from the beginning with more details.
Knowing Your Kitchen
Take a good look at your Android Studio interface in Figure 9. Be brave to fiddle around the interface by clicking away the many menu items to discover the many features that Android Studio has offered.
For example, to access the various tools windows in Android Studio, select View > Tool Windows and you will be presented with a list of tool windows to choose from (Figure 15). If you look at the fringes of the interface, you will notice that they also appear as menu items there. Clicking on these items will toggle their appearances on the screen as different window panes.
|
Figure 15: Access Tool Windows
|
You may feel overwhelmed. Relax! Let me assure you that that is normal and you will get to know these features better when you do more and more development with Android Studio.
Tip:
Overtime, your Android Studio interface may get very messy. Fret not!, you can reset it back to its virgin state by selecting Window > Restore Default Layout or Shift + F12.
I shall leave you to fiddle around the Android Studio for a while...
Starting to Cook
If you want to spice up your app, you have got to understand how Android Studio treat and cook your app first.
Look at the Project pane on your Android Studio screen. The Project window acts as file explorer showing all the files organized in tree hierarchy in your Android project. Double-clicking on any file under each node will open up its content in the text editor window. We will walk through some of the more important files one by one. They are all located under the app node. Did you see it?
Layout Editor
Expand the app node in the Project pane, then navigate all the way through the child nodes, app > src > main > res > layout until you find this file called activity_my.xml. Double-clicking on this file, you will be presented with the layout code in the Layout Editor pane and a visual layout in a Preview pane (Figure 16).
|
Figure 16: Layout
|
What you see is the UI layout of your first Android program (or activity in Android term), i.e. the MyActivity that you have defined in Figure 8. It is written in XML and what it does is, among other things, define a RelativeLayout (Layout) object that contains a TextView (View) object (Figure 17).
|
Figure 17: Layout Code in XML
|
The TextView object holds a text value of "Hello World!" which you saw on the AVD through this line:
android:text="@string/hello_world"
You may notice a discrepancy here, how come it is "@string/hello world" not "Hello World!"! Soon you will find out why.
The visual representation of this XML layout is shown in the Preview pane (Figure 18). It does show "Hello World!". You can toggle this Preview pane by clicking on the vertical menu item called Preview located on the right fringe of the Android Studio screen.
|
Figure 18: Visual Preview
|
Any changes you make to the XML layout will be reflected in the preview pane instantly. Let's try it out now.
String Resources
Navigate through app > src > main > res > values until you find this file called strings.xml. Double-clicking on this file, you will be presented with some string values in XML format in the Editor window (Figure 19). This file should contain all the string values to be used in your app.
|
Figure 19: String Resources
|
You have just found the answer to your question yourself.
Answer:
The value of "Hello World!" is being assigned to a static variable called hello_world. The "@string/hello world" that you saw in the activity_my.xml file in Figure 17 is actually a reference to the variable called hello_world. It is the Android way of referring to static resources of string type in XML. The advantages of using resources in this way are obvious - reusability and maintainability. You may simply assign the value of "Hello World!" directly to android:text in activity_my.xml, but it is strongly discouraged.
Add a new variable called my_message and give it a value of "I love Android!" in the strings.xml file. Like this (Figure 20):
|
Figure 20: String Resources
|
Move back to the activity_my.xml file by clicking the corresponding tab on top of the Layout Editor pane and add a new TextView object to display my_message like this (Figure 21):
|
Figure 21: Edit activity_my.xml
|
Turn your head towards the Preview pane, what did you see? Ooh, something is amiss. The two strings have got in each other's way (Figure 22).
|
Figure 22: Something is amiss
|
In the activity_my.xml file, do these:
The activity_my.xml should look like this (Figure 23):
|
Figure 23: Debugged activity_my.xml
|
Turn your head towards the Preview pane (slowly lest it sprains the neck) again, what did you see this time? Hurrah! it's fixed (Figure 24).
|
Figure 24: It's fixed!
|
Design Editor
I must confess I have been keeping something from you. If you look at the bottom left of the layout editor pane while in activity_my.xml, you will notice two tabs marked as Design and Text respectively and the Text tab is currently highlighted. Yes, you have been typing away plain XML text all this while. Click the Design tab and be surprised! - Android Studio has given you a graphical tool to assist you in the layout design (Figure 25)
|
Figure 25: Design Mode
|
The use of this design interface is very intuitive. The middle pane presents a visual screen of your app on a virtual device. It is showing Nexus 4 by default. You can change to difference device like this (Figure 26):
|
Figure 26: Change Virtual Device
|
The left pane is the Palette that contains layouts, widgets, and many other components that you can just drag and drop onto the virtual device. The right pane shows the Component Tree of all Layout and Views objects used in the project on the top half and the corresponding Properties of the highlighted item on the bottom half. In Figure 26, it is showing the properties of the highlighted LinearLayout object.
Let's try out the design editor by adding and displaying an image on the device screen.
Drawable Resources
First you have to add an image to your project as a drawable resources. I have attached an image file called "android_robot.png" that I have used at the beginning of this article. Download it to your computer and follow these steps your image asset:
-
Right-click the res node in the Project pane, select New > Image Asset as shown in Figure 27:
|
Figure 27: New Image Asset
|
-
You will be presented with the Asset Studio form (Figure 28) for managing resources in your Android project. Fill out the parameters as shown in Figure 28. Select the "android_robot.png" image file that you have downloaded onto your computer.
|
Figure 28: Asset Studio
|
Android system will perform scaling and resizing to make the image work on different screen resolutions, as you can see in the Preview how this image will appear in different screen resolutions - MDPI, HDPI, XHDPI, and XXHDPI. They will be stored in separate folders, namely drawable-mdpi, drawable-hdpi, drawable-xhdpi, and drawable-xxhdpi. The Android operating system will select one of these images for display based on the screen resolution of the device. To find out more about how Android supports multiple screens, visit Android Developers.
Once it is ready, go Next.
-
Another screen will show you the folder that each processed image will be saved to (Figure 29). Click Finish.
|
Figure 29: Asset Studio
|
Once it is done, go Next.
-
Out of curiosity, expand all the drawable folders in the Project pane, you will find that they all contain "android_robot.png", but clicking on each of them will reveal that they are of different sizes (Figure 30).
|
Figure 30: Drawable Image
|
Once it is done, go Next.
Adding Image
From the Widgets section of the Palette pane, drag and drop an ImageView and placed it above the first TextView on the virtual device screen (Figure 31).
|
Figure 31: Add ImageView Widget
|
Turn you head to the right. You should find an imageView1 being added under the LinearLayout node in the Component Tree section. This is the default id of the ImageView widget that you have just added to the screen. You can change the position of the View objects by drag and drop. This is useful if you have difficulty positioning your widgets on the screen.
Click to highlight the imageView1 in the Component Tree, turn your head downwards you will find the various properties of this View object in the Properties section. Scroll the list of properties in this section, you should find an id property where you can change its value (Figure 32).
|
Figure 32: Asset Studio
|
Scroll to find the src property (Figure 33).
|
Figure 33: Asset Studio
|
Click on the browser button beside the src property, you will presented with a Resources screen to select the image for the imageView1 object (Figure 34). Select "android_robot" and click OK.
|
Figure 34: Select an Image Resource
|
You have successfully added an image to your app (Figure 35).
|
Figure 35: Added an Image to the Screen
|
Run your app on the AVD and see for yourself (Figure 36).
|
Figure 36: Added an Image to the Screen
|
If you switch back to the Text mode, you will find the new entry added in the activity_my.xml file as shown in Figure 37. The new ImageView object has been given a unique resource ID "@+id/imageView1". Every resource ID comes in the form of "@+id/name" where the plus sign indicates that this is a new ID.
|
Figure 37: Debugged activity_my.xml
|
How do you find the dish now, taste better? Now, I have a secret to tell you. Read carefully...
R.java
Android has been quietly compiling all the resources into a Java class called R.java. R stands for Resources. Whenever your app is compiled, Android generates/regenerates the R class, which contains resource IDs for all the resources in the res directory of your project. You should leave R alone. You can find it by following the trail in Figure 38.
|
Figure 38: R.java
|
For each type of resource, there is an R subclass. For example, R.string for all string resources. Each resource is assigned a unique integer as its resource ID so that you can use to retrieve the resource. You can find all the resources that are used in the project being declared as public static final int variables in their respective Java classes which are also public static final. As they are subclasses of R, they can be accessed by calling R.<class name>, e.g. R.string.
R.string
In the R.string class, it contains "hello_world" and "my_message" and other strings variables in the "res/values/strings.xml" file (Figure 39). In fact, you do not have to name your string resource file as strings.xml, as long as the structure of the file follows that in Figure 39 and is placed in the "res/value" directory, Android will treat it as string resource file and automatically includes its content in the string class of R.java.
You can access the string resources anywhere in the Java code by calling R.string.<variable name>, e.g. R.string.hello_world.
To access it from XML, you have done it before, @string/<variable name>, e.g. @string/hello_world.
|
Figure 39: String Resources
|
R.id
The R.id contains imageView1 variable which refers to the ImageView object in the activity_my.xml file (Figure 37). You can access this object in the Java code like this:
ImageView iv = (ImageView)this.findViewById(R.id.imageView1);
R.layout
The R.layout contains activity_my variable which refers to the activity_my.xml located in res/layout. Any Activity that wants to use this layout file will do this in its onCreate method:
setContentView(R.layout.activity_my);
So far, we have been dealing with all static components. Who is going to take care of all the dynamic interaction with users? That brings us to the Activities.
Activity
An Activity in Android is like what the name suggests, it is a program that takes care of interactive activities with the users. It is actually a Java class. For an Activity to serve its purpose, it needs a UI which it taps on R.layout class, it needs to monitor and respond to events which it works with R.id class, and so on. In other words, every screen on your Android device is created via an Activity and every Activity depends on the various resources in the R class to do its job.
The Activity in your project can be found by following the trail shown in Figure 40. It is called "MyActivity.java" (as defined in Figure 8). Based on the template that you have chosen in Figure 7, Android Studio has created a default Activity class complete all the boilerplate code which would saves you a lot of development time.
|
Figure 40: MyActivity Class
|
The most indispensable piece of code in every Activity is the onCreate method which performs the initial setup such as:
Every Activity in the Android system is governed by a well-defined lifecycle. It has essentially four states and a number of key loops. You may take a look at Figure 41 which I borrowed from Android Developers for a quick overview of the lifecycle. I will have to defer any detailed discussion to another occasion lest it should overwhelm you.
|
Figure 41: Activity Lifecycle
|
Source: Android Developers
You can add as many Activities as per your project requirements. Let's try adding a new Activity to your app. Follow these steps:
- Follow the trail as shown in Figure 42 to create a new Activity. This time you will try out the Login template.
|
Figure 42: Create New Activity
|
Once it is ready, go Next.
-
You will be presented with a form as shown in Figure 43. Use the default values for Activity Name, Layout Name, Title, and Package name fields. The Hierarchical Parent field lets you indicate the parent Activity that this new Activity should navigate to when the user tap the device's back button. Leave it blank. Lastly, uncheck the Include Google+ sign in checkbox as we are not using this feature.
|
Figure 43: Set up New Activity
|
Click Finish to create the new Activity called LoginActivity.
-
Navigate to the Design view of activity_login.xml to view the visual layout of your newly created Activity - LoginActivity (Figure 44). It has the standard features of a typical sign in screen - an email field, a password field, and a sign in button. I have a requirement, that is I want your app to be able to navigate to MyActivity upon the click of the sign in button.
|
Figure 44: activity_login.xml
|
-
Double-click the sign in button, a pop box will appear (Figure 45). Copy the id value from the pop up box. This button resource has been assigned a resource ID of "@+id/email_sign_in_button". You can find this id entry in the android:id attribute of the Button element in the newly created layout file called activity_login.xml. (You should be able to find this id value listed as one of the static variables inside the id class of R.java if you care to look it up, but be prepared to get lost in the ocean of code, and where you are there, remember see no touch.)
|
Figure 45: activity_login.xml
|
-
Switch to the LoginActivity.java in the code editor, press Ctrl + F to activate the search box, then paste the id value that you have copied in the previous step into the search box. Walah! The editor has found it instantly (Figure 46).
|
Figure 46: LoginActivity.java
|
-
Replace the code inside the onClick method like this:
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), MyActivity.class);
startActivity(intent);
}
-
Place your mouse over one of the "Intent" word, it will complain of some error (Figure 47). This is because the Intent class is contained inside the android.content.Intent package which is not yet included. Fret not! Just click on it once followed by Alt + Enter and this problem will go away instantly. Thanks to Android Studio. (You should be grateful that you have heeded my advice. ;P )
|
Figure 47: LoginActivity.java
|
An Intent object is the Android's way of describing a message stating its "intention" to do something, i.e. to navigate to MyActivity. This Intent object is then passed to the startActivity method to carry out the intended action.
Alright, the LoginActivity is done, can we test it on the AVD? No, not yet. In the current setup, the Activity that will be launched at start up is MyActivity, LoginActivity will never have a chance to run. In the new requirement, we want the LoginActivity to be the launcher Activity, how can we achieve this?
Let's me introduce you to the last but not least important guest of today - the Android Manifest.
Android Manifest
In every Android application, you will find a file called AndroidManifest.xml file in its root directory. Android system will not allow your app to run if it does not have this file. The manifest file is an XML file that holds all the configuration information about your app that the Android system must know before it allows to run any of the app's code - information from app’s name, icon, version, to hardware and software requirements, and it even filters the Intents that coming into the app. What a busy body right?. You may liken it to the Web.config file of an ASP.NET application. I would think of it as the command and control center of an app. Everything you want to know about the app or to do with the app, ask AndroidManifest.xml. Android Developers has a comprehensive list of what an Android Manifest does, check it out yourself.
Coming back to our app, follow these steps to modify its AndroidManifest.xml:
- Follow the trail as shown in Figure 48 to navigate to AndroidManifest.xml. Spend some time to browse its contents, did you see some familiar faces?
|
Figure 48: AndroidManifest.xml
|
Notice that there are two activities block being declared inside the AndroidManifest.xml file - MyActivity and LoginActivity. The difference between them is that MyActivity has been declared with an intent-filter element.
An Intent Filter enables a component such as an Activity to advertise their capabilities, i.e. the kinds of intents it can respond to. Android system will only launch a component to handle an intent if its capabilities is made known in the intent filter.
In our case, by specifying an action attribute of android.intent.action.MAIN and an category attribute of android.intent.category.LAUNCHER, the intent-filter has declared MyActivity as the top-level entry point into your app and also be listed in the application launcher.
-
Once you understand the working of intent filter, then the solution is easy peasy. Move the intent-filter element from MyActivity to LoginActivity in the AndroidManifest.xml. That's it.
|
Figure 49: Modified AndroidManifest.xml
|
-
Test it out on the AVD. See that it will launch in the Sign in screen (Figure 50), pressing the button should switch to the My First Android App screen (Figure 36).
|
Figure 50: activity_login.xml
|
Getting Real
You have done up your app. Don't you want to try out your app on a real device? Why not, let's get real.
If you own an Android device (most likely), you can develop and debug your Android apps just as you have done on the emulator. However, before you can start, you have to set up your device for development purpose. You are advised to follow this comprehensive guide by the Android Developers that covers all computer platforms to set up your device for development. Figure 51 shows the state of my phone being enabled for development.
|
Figure 51: Enabled Developer Options
|
When your device has been set up, connect it to your computer and follow these steps:
-
You have done this before when you first set up your emulator (Figure 10). On the Android Studio's menu bar, click app > Edit Configurations... or click Run > Edit Configurations.... But this time, select USB device in the Target Device section (Figure 52).
|
Figure 52: Edit Configurations
|
Once it is done, click OK.
-
Enjoy your app on your device. Catch the glimpse of the app running on my device from Figures 53 to 55.
|
Figure 53: The App Launcher
|
|
Figure 54: Sign in
|
|
Figure 55: Hello World!
|
Signing Ceremony
At some point in the future, you would want to consider publishing your Android apps so that they are available to users. For that, you should refer to the official guide on this matter at Android Developers site. However, before you can release your apps to the general public, you are required to sign them with a digital certificate the private key of which is to be held by you the developer. The Android system will not install or run any unsigned apps. It is a way for Android system to identify the author of an app and to build trust between apps. You can use self-signed certificates for this purpose.
For this reason, even apps in debugging stage also require to have a signed certificate before they can be run on an emulator or physical device. But we do not remember doing it when we run our app in the AVD or physical device. How come? That is because Android Studio has taken care of that automatically without bothering us. Let's read what the Android Developers has said about this:
Quote:
When you build in debug mode the Android SDK build tools use the Keytool utility (included in the JDK) to create a debug key. Because the SDK build tools created the debug key, they know the debug key's alias and password. Each time you compile your application in debug mode, the build tools use the debug key along with the Jarsigner utility (also included in the JDK) to sign your application's .apk file. Because the alias and password are known to the SDK build tools, the tools don't need to prompt you for the debug key's alias and password each time you compile...The debug signing process happens automatically when you run or debug your application
However, when you build your app in release mode, you have to use your private key to sign. Let's step through the process of signing your app using Android Studio:
- Select Build > Generate Signed APK... (Figure 56):
|
Figure 56: Generate Signed APK
|
-
You will be presented with a form as shown in Figure 57. The Choose existing... button is for signing your apps with a key from an existing keystore file. We will create a new keystore file, so click Create new....
|
Figure 57: Generate Signed APK Wizard
|
-
The New Key Store form appears (Figure 58). In the Key store path, enter or browser to the location where you want to save your keystore file and give your keystore file a name. A key store file, as its name suggested, is a repository of security certificates (keys). Complete the other fields.
|
Figure 58: New Key Store
|
Before you click OK, you have to remember these values securely.
- Keystore Password is required to access a keystore.
- Key Alias is required to address the key to use.
- Key Password is required to access a key.
Click OK, the keystore will be created.
- You will be presented with the Generate Signed APK Wizard form (Figure 59), just go Next.
|
Figure 59: Generate Signed APK Wizard
|
-
Choose release build type, then Finish (Figure 60).
|
Figure 60: Generate Signed APK Wizard
|
-
You can view the progress of the build process by expanding the Messages menu at the bottom of the Android Studio screen (Figure 61).
|
Figure 61: Generated Signed APK
|
So far so good, Android Studio has successfully generated the signed APK. A signed installation file called app-release.apk can now be found at app directory inside your project root directory (Figure 60).
Spreading the Good News
You have developed your first Android app, got it signed into an APK installation file. You are eager to show it to your friends, aren't you? That is easy peasy, simply attach the APK to your email to them. Installation is just a click on the attached APK file on their android device. Wait! there is a catch. Your friends will be alerted with a message from their device that says something to that effect that the APK file is of unknown source as it did not come from Google Play and will be blocked by default. So in your message to them, you should explain this to them (to allay their fear) and teach them how to unblock the installation - on their device, go to Security > uncheck Unknown Sources. You may want to email a copy to yourself and try it out first.
There are many other ways to distribute your apps, find out more from Android Developers.
Getting Resourceful
Everything that you need to work on your app lives in this neighborhood - app > src > main (Figure 62). Its residents consists of the families of java, res, and the lonely but powerful AndroidManifest.xml. You have already met some of them while working on your project. However, there are still many members in the res family that you have not yet met. So, let's pay them a visit to get to know them better.
|
Figure 62: app Directory
|
res for Resources, The res directory is the repository of all the resources that your Android project needs. Resources are anything that you can imagine that can be used in your Android app, such as text, graphics, sounds, colors, files, dimensions, menu, animation, and many many more. Android will group them into into separate resource directories based on and named after their resource types like drawable, layout, menu, values, and values-w820dp in my app (Figure 63). You can find out more about the resource types here.
When your app is compiled, Android generates a R.java class (Figure 38), which contains resource IDs for all the resources in the res directory. For each type of resource, there is an R subclass (for example, R.string for all string resources, R.drawable for all drawable resources, and so on), and for each resource of that type, there is a static integer (for example, R.drawable.android_robot, R.string.my_message, and so on). This integer is the resource ID that you can use to retrieve your resource.
|
Figure 63: res Directory
|
-
drawable contains graphical resources like bitmap files and shapes. Drawable resources are further optimized into different sizes to suit different screen resolutions. They are stored in separate directories, namely drawable-mdpi, drawable-hdpi, drawable-xhdpi, and drawable-xxhdpi. The Android operating system will select one of these images for display based on the screen resolution of the device. To find out more about how Android supports multiple screens, visit Android Developers. In your app, you would have two graphic resources - "android_robot.png" and the "ic-launcher.png", in all the drawable directories. The "ic-launcher.png" is used as the default image for the launcher icon on your device.
-
layout contains XML files that define the visual structure for a user interface in Android. You can define layouts at design time using XML or creating them on the fly using Java code. The layout directory here contains the XML files that define the various layouts for your Android project at design time. So far, we have two layout files - activity_login.xml and activity_my.xml, one each for the two Activities in our project. Let's revisit the activity_my.xml again and look closer this time:
-
First, the ImageView object.
<ImageView
android:layout_width="89dp"
android:layout_height="wrap_content"
android:id="@+id/imageView1"
android:src="@drawable/android_robot"
android:layout_weight="0.09" />
It has been assigned the "android_robot" drawable resource via:
android:src="@drawable/android_robot"
This is the XML way of referencing resources in Android => @resourceType/<resourceName>
If you want to access this drawable resource in Java, follow this syntax => R.resourceType.<resourceName>
R.drawable.android_robot
Note:
There are two ways to access a resource in Android:
-
Next, the LinearLayout declaration.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MyActivity"
android:orientation="vertical"
android:weightSum="1">
Pay attention to these, if you see number instead of @diman/xxx_xxx_margin then double click on that line to reveal the true identify.
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
Intuitively, they define the dimension of some sorts, but you would expect number instead of some text that reads @dimen/xxx_xxx_margin. The answer lies with one of its family members - dimens.xml in the values resource directory.
-
dimens.xml defines the dimension resources that you can use in your Android project. Notice that there are two dimens.xml - one each in values directory and values-w820dp directory. The dimens.xml in the values directory looks like this:
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
While the dimens.xml in the values-w820dp directory looks like this:
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
There are two dimension resources being defined in the dimens.xml inside the values directory - "activity_horizontal_margin" and "activity_vertical_margin" both have the same value of 16dp, while only "activity_horizontal_margin" with the value of 64dp is defined in the dimens.xml inside the values-w820dp directory. Do they look familiar? (Scroll down a bit.) Oh yes, they appeared in the LinearLayout declaration of activity_my.xml file. Again, this is the how Android refers to resources in the XML way => @resourceType/<resourceName>. I shall not mention this anymore.
You are going to ask, "Which one of these two will be used by the app?" :confused: That would bring us to the topic of localization of resources in Android. Every app should provide alternative resources to support specific device configurations. Android will auto detect the prevailing device configuration and selects the appropriate resources for your application. You have already seen one example in drawable where alternative resource directories being assigned to store graphics optimized for different screen resolutions. It is the same in this case, where the values directory is the default resource directory, while the values-w820dp directory is the alternative one. Both serve the same purpose for storing strings, dimensions and styles resources of the same names but of different values. Android will use the dimens.xml in the values-w820dp directory when the screen size of the device is more than 820dp in available width. Any resources not defined in the values-w820dp directory will be referred to the default one, that is the dimens.xml in the values directory. So if your device is more than 820dp in width, Android will set the "activity_horizontal_margin" to 64dp and the "activity_vertical_margin" to 16dp. You can learn more about localization of resources here.
But what is dp? more :confused: It is an acronym for density-independent pixels. You can use dip too. They are the same. It is density independent in the sense that when you define something of 16dp or 16 dip, it would be rendered the same size on any screen. What a perfect solution for the many screen sizes of mobile devices. It is the recommended unit of dimensions for Android app. Of course, there is no stopping you from using some other units of measurement.
Android has another unit created specifically for text. It is called scale-independent pixels or sp in short. (sip? No, there is no sip. Don't try your luck.) It is similar to dp but with one twist - it would allow users to change font size without affecting the size of other elements. You are recommended to use sp for any text.
-
strings_xxx.xml defines the string resources that you can use in your Android project. It resides in the values resource directory. So far, we have two strings XML files in our project - "strings.xml" and "strings_activity_login.xml", one each for the two activities in our project. I have already covered string resource type quite substantially, so let's move on.
-
styles.xml defines the styles and themes for a user interface. It resides in the values resource directory. It can be applied to any View components, Activities, or the entire application. You can learn more about styles and themes here.
-
menu contains all the menu resources like the option menu, action bar, context menu, and pop up menu that you can use in your Android project. There is only one menu resource file my.xml in our project and it looks like this (Figure 64):
|
Figure 64: menu Resource
|
The my.xml creates an action bar called "Settings" on MyActivity. By now, you should be able to interpret the XML syntax contained in it.
At the Rest Stop
Is this the rest stop? Phew! I thought I were not going to make it. This journey seemed endless. Nevertheless, all's well ends well. You have done some real stuff with Android, from developing a simple app, debugging, testing, to publishing it. Keep it up! Meanwhile, have a well-deserved break, and we shall meet again.
Reference