Top Android Performance Problems Faced by App Developers - AndroidAuthority
Top Android Performance Problems Faced by App Developers - AndroidAuthority
From a traditional software engineering point of view there are two aspects to optimization. One is local optimization where a
particular aspect of aprograms functionality can be improved, that is theimplementation can be improved, speeded-up. Such
optimizations can include changes tothe algorithms used and the programs internal data structures.The second type of
optimization is at a higher level, the level of design. If a program is badly designed it will be hard to get good levels of
performance or efficiency. Design level optimizations are much harder to fix (maybe impossible to fix) late in the development
lifecycle, so really they should be resolved during the design stages.
ADVERTISEMENT
When it comes to developing Android apps there are several key areas where app developers tend to trip-up. Some are design
level issuesand some are implementation level, either way they can drastically reduce the performance or efficiency of an app.
Here is our list of the top 4 Android performance problems faced by app developers:
Battery
Most developers learnt their programming skills on computers connected to the mains electricity. As a result there is little taught
in software engineering classes about the energy costs of certain activities. A study performed by Purdue University
(http://research.microsoft.com/en-us/people/mzh/eurosys-2012.pdf) showed that most of the energy in smartphone apps is
spent in I/O, mainly network I/O. When writing for desktops or servers, the energy cost of I/O operations is never considered. The
same study also showed that65%-75% of energy in free apps is spent inthird-party advertisement modules.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 1/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
The reason for this is because the radio (i.e. Wi-Fi or 3G/4G) parts of a smartphone use a energy to transmit the signal. By default
the radio is off (asleep), when a network I/O request occurs the radio wakes up, handles the packets and the stays awake, it
doesnt sleep again immediately. After a keep awake period with no other activity it will finally switch off again.Unfortunately
waking the radio isnt free, it uses power.
As you can imagine, the worse case scenario is when there is some network I/O, followed by a pause (which is just longer than the
keep awake period) and then some more I/O, and so on. As a result the radio will be use power when it is switched on, power
when it does the data transfer, power while it waits idle and then it will go to sleep, only to be woken again shortly afterwards to
do more work.
Rather than sending the data piecemeal, it is better to batch up these network requests and deal with them as a
block.
There are three different types of networking requests that an app will make. The first is the do now stuff, which means that
something has happened (like the user has manually refreshed a news feed) and the data is needed now. If it isnt presented as
soon as possible then the user will think that the app is broken. There is little that can be done to optimize the do now requests.
The second type of network traffic is the pullingdown of stuff from the cloud, e.g. a new article has been updated, there is a new
item for the feed etc. The third type is the opposite of the pull, the push. Your app wants to send some data up to the cloud.
These two types of network traffic are perfect candidates for batch operations. Rather than sending the data piecemeal, which
causes the radio to switch on and then stay idle, it is better to batch up these network requests and deal with them in a timely
manner as a block. That way the radio is activated once, the network requests are made, the radio stays awake and then finally
sleeps again without the worry that it will be woken again just after it has gone back to sleep. For more information on batching
network requests you should look into theGcmNetworkManager
(https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager)API.
To help you diagnose any potential battery issues in your app, Google has a special tool called theBattery Historian
(https://github.com/google/battery-historian). It recordsbattery related information and events on an Android device (Android 5.0
Lollipop and later: API Level 21+) while adevice is running on battery. It then allows you to visualize system and application level
events on a timeline, along withvarious aggregated statistics since the device was last fully charged. Colt McAnlis has a
convenient, but unofficial, Guide to Getting started with Battery Historian
(https://docs.google.com/document/d/1CSTRAaCtbjTe2rs2vzra6-PViMkfPJC9DVWg7NbXqYk).
Memory
Depending on which programming language you are most comfortable with, C/C++ or Java, then yourattitudeto memory
management is going to be: memory management, what is that or malloc is my best friend and my worse enemy. InC,
allocating and freeingmemory is a manual process, but in Java, the task of freeingmemory is handled automatically by the
garbage collector (GC). This means that Android developers tend to forget about memory. They tend to be a gung-ho bunch who
allocate memory all over the place and sleep safely at night thinking that the garbage collector will handle it all.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 2/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
And to some extent they are right, but running thegarbage collector can have an unpredictable impact on your apps
performance. In fact for all versions of Android prior to Android 5.0 Lollipop, when thegarbage collector runs, all other activities
in your app stop until it is done. If you are writing a game then the app needs to render each frame in 16ms, if you want 60 fps
(https://www.youtube.com/watch?v=CaMTIgxCSqU). If you are being tooaudacious with your memory allocations then you can
inadvertently trigger a GC event every frame, or every few frames and this will cause you game to drop frames.
For example, using bitmaps can cause trigger GC events. If the over the network, or the on-disk format, of an image file is
compressed (say JPEG), when the image is decoded into memory it needs memory for its full decompressed size. So a social
media app will be constantly decoding and expanding images and then throwing them away. The first thing your app should do is
re-use the memory already allocated to bitmaps. Rather than allocating new bitmaps and waiting for the GC to free the old ones
your app should use a bitmap cache. Google has a great article onCaching Bitmaps
(http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html) over on the Android developer site.
Also, to improve the memory foot print of your app by up to 50%, you should consider using the RGB 565 format
(http://developer.android.com/reference/android/graphics/Bitmap.Config.html).Each pixel is stored on 2 bytes and only the RGB
channels are encoded: red is stored with 5 bits of precision, green is stored with 6 bits of precision and blue is stored with 5 bits
of precision. This is especially useful for thumbnails.
Data Serialization
Data serialization seems to be everywhere nowadays. Passing data to and from the cloud, storing user preferences on the disk,
passing data from one process to another seems to all be done via data serialization. Therefore the serialization format that you
use and the encoder/decoder that you use will impact both the performance of your app and the amount of memory it uses.
The problem with the standard ways of data serialization is that they arent particularly efficient. For example JSON is a
greatformat for humans, it is easy enough to read, it is nicely formatted, you can even change it. However JSON isnt meant to be
read by humans, it is used by computers. And all that nice formatting, all the white space, the commas and the quotation marks
make it inefficient and bloated. If you arent convinced then check outColt McAnlis video on why these human-readable formats
are bad for your app (https://www.youtube.com/watch?v=IwxIIUypnTE).
Many Android developers probably just extend their classes with Serializable in a hope to get serialization for free. However in
terms of performance this is actually quite a bad approach. A better approach is to use a binary serialization format. The two best
binary serialization libraries (and their respective formats) are Nano Proto Buffers andFlatBuffers.
FlatBuffers (http://google.github.io/flatbuffers/) is an efficient cross platform serialization library for C++, Java, C#, Go, Python and
JavaScript. It was originally created at Google for game development and other performance-critical applications. The key thing
about FlatBuffers is thatit represents hierarchical data in a flat binary buffer in such a way that it can still be accessed directly
without parsing/unpacking. As well as the included documentation there are lots of other online resources including this video:
Game On! Flatbuffers (https://www.youtube.com/watch?v=iQTxMkSJ1dQ) and this article:FlatBuffers in Android An
introduction (http://frogermcs.github.io/flatbuffers-in-android-introdution/).
Threading
http://www.androidauthority.com/topandroidperformanceproblems666234/ 3/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
Threading
Threading is important for getting great responsiveness from your app, especially in the era of multi-core processors. However it
is very easy to get threading wrong. Because complex threading solutions require lots of synchronization, which in turn infers the
use of locks (mutexes and semaphores etc) then the delays introduced by one thread waiting on another can actually slow your
app down.
By default an Android app is single-threaded, including any UI interaction and any drawing that you need to do for the next frame
to be displayed. Going back to the 16ms rule, then the main thread has to do all the drawing plus any other stuff that you want to
achieve. Sticking to one thread isfine for simple apps, however once things start to get a little more sophisticated then it is time
to use threading. If the main thread is busy loading a bitmap then the UI is going to freeze
(http://developer.android.com/training/articles/perf-anr.html).
Things that can be done in a separate thread include (but arent limited to) bitmap decoding, networking requests, database
access, file I/O, and so on. Once you move these types of operation away onto another thread then the main thread is freer to
handle the drawing etc without it becoming blocked by synchronous operations.
For simple threading many Android developers will be familiar with AsyncTask
(http://developer.android.com/reference/android/os/AsyncTask.html). It is a class thatallows an app to perform background
operations and publish results on the UI thread without the developer having to manipulate threads and/or handlers. Great But
here is the thing, allAsyncTask jobsareexecuted onthe samesingle thread. Before Android 3.1 Google actually
implementedAsyncTask with apool of threads, which allowed multiple tasks to operate in parallel. However this seemed to cause
too many problems for developers and so Google changed it back to avoid common application errors caused by parallel
execution.
What this means is that if you issue two or threeAsyncTask jobs simultaneously they will in fact execute in serial. The
firstAsyncTask will be executed while the second and third jobswait. When the first task is done then the second will start, and so
on.
Wrap-up
There are of course other performance pitfalls for Android app developers to avoid however getting these four right will ensure
that you app performs well and dont use too many system resources. If you want more tips on Android performance then I can
recommendAndroid Performance Patterns (https://www.youtube.com/playlist?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE),
acollection of videos focused entirely on helping developers write faster, more efficientAndroid apps.
Posted In
Android Development (http://www.androidauthority.com/android-development/)
Tags
Android Developer Tools (http://www.androidauthority.com/tag/android-developer-tools/), Java
(http://www.androidauthority.com/tag/java/)
Android Developer Tools (http://www.androidauthority.com/tag/android-developer-tools/), Java
(http://www.androidauthority.com/tag/java/)
http://www.androidauthority.com/topandroidperformanceproblems666234/ 4/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
5Comments AndroidAuthority
1 Login
Jointhediscussion
KunalNarang amonthago
Thanksforthisarticle!!
1 Reply Share
alex amonthago
Excellentarticle!Bookmarkingit.
1 Reply Share
AlfredBeiley amonthago
ThanksGaryfornicearticle.ialsosharewithmyfriends.
Reply Share
KarlyJohnston amonthago
Articleslikethisarethereasonicomehere,tolearn...
Reply Share
ChristianBrggemann amonthago
SHOW ALL COMMENTS
Aboutflatbuffers:
Therearesituationswhenthesecomeinhandy,butinmostcasesusingJSON(atleastifit'ssentgzipped)is
http://www.androidauthority.com/topandroidperformanceproblems666234/ 5/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn04.androidauthority.net/wp-content/uploads/2016/02/Screenshot_2016-02-11-13-34-21-16x9-1080p.jpg)
In this post, were going to build a basic, functioning app. This app, if all goes to plan, will not only serve as a learning opportunity but
also as something you can reverse engineer and reappropriate for your own ends. If youre so inclined, you can change a few details,
compile it and distribute it/sell it. All the code, images and resources are available on GitHubhere
(https://github.com/treehousefrog/Crystalize-Part-1), or you can follow the process step-by-step and build your own version.
ADVERTISEMENT
This is a two-part series, so in part one well only be making something very bare bones. In the next installment, things will get a little
more refined and useful.
I wanted to create something that would be simple and that would be easy to turn into other things. I was going to go with a quiz but
that feels too much like a game (and a game might make an interesting future post). So instead, I chose a test. Yep, thats certainly
less fun!
Ive always wanted to know Morse code, the phonetic alphabet and chemical symbols. I just think it would be awesome if one day
those skills came in handy in a real world situation and everyone would be super impressed (Wait a minute, thats Morse code for the
chemical symbol for potassium!). So this app is going to be a learning tool test that you can use every day to learn that kind of stuff.
If youd like to learn something else though, you will just be able to change the questions and answers. You can make it into a quiz,
into a revision tool you name it!
http://www.androidauthority.com/topandroidperformanceproblems666234/ 6/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn03.androidauthority.net/wp-content/uploads/2016/02/what-to-click.png)
You may want to call the new appCrystalize, or if you already have different plans, you can call it anything else. You can also choose
your own company domain of course. For simplicity, I recommend leaving the name of the activity and layout as the defaults as that
way well be on the same page.
Now head over to the activity_main.xml file and take a look around. activity_main.xml is the .xml file that will define the layout of
MainActivity.java. For the most part, each activity (screen) in an app will have two corresponding files: the .xml which sets out the
layout and the java which defines the behavior of the app and what happens when you click on different elements. If youve ever built
a website, the XML is used in a similar way to how HTML is used to build a web pages, in fact XML and HTML are related.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 7/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn03.androidauthority.net/wp-content/uploads/2016/02/screen-1.png)
Right now, the activity_main.xml is pretty barren and uses a relative layout with a single TextView saying Hello World!. Read through
this page and you should find its fairly self-explanatory what everything does. android:layout_height for instance sets the height,
while android:text tells us what text to show. There are many more instructions we can add to further customize the way things look
but all thats strictly necessary in most cases is height and width.
Lets start mixing things up. Open activity_main.xml. Were going to change the layout from relative to linear, meaning that the
elements we add will simply line up on top of one another. Were also adding a line setting the gravity to center so that the edit text
will appear in the middle of the screen. We do this by simply adding android:gravity = center somewhere within the triangular
brackets for the linear layout.
<?xmlversion="1.0"encoding="utf8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:gravity="center"
tools:context="com.nqr_productions.crystalize.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sansserifthin"
android:text="HelloWorld!"/>
</LinearLayout>
If you take a look at the designer, weve now moved the text to the center of the screen. Were going to be making this our splash page,
so having some text in the middle there will work well for our app name.
(Note that you can switch between the designer and the code for the xml youre viewing using the tabs along the bottom.)
And with that in mind, it will probably make sense to change the name of activity_main.xmlto something else. Right click on the tab
and rename it as splash_page.xml. Instead of OK, the option to go ahead with the change is Refactor. This means that the name of
the app is going to change in every reference and instance so far so it will now say setContentView(R.layout.splash_page); in the
main activity, without you having to change anything yourself.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 8/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
But a little bit of tiny text isnt really enough to look like a nice splash page. Instead, we need to increase the size of that text and the
font. And we need it to be our app name!
So change Hello World to Crystalize. This is what I have decided to call the app its a reference to Crystalized intelligence in
psychology, which is basically a fancy term for knowledge (as opposed to fluid intelligence which is more relating to IQ, memory, focus
etc.). Yep, Im a nerd.
Were also going to make the text a little bigger, so add this line to theTextView:
android:textSize="50dp"
DP means density independent pixels and that means that it should look a similar size on whatever type of device youre using.
You can now either run the app or just view it in the designer to see how its going to look.
So next, were going to pick a color for the text and for the background. To do that, why not head over to Paletton
(http://www.paletton.com), which is a great tool for picking colors that will work well together. Im going to go for three adjacent colors,
which will help us to get that smart, minimal Material Design look.
Pick the colors you like, then click Tables/Export to find the color codes. You can save this for future reference.
I think an app called Crystalize needs a color palette that uses cool hues. So Im going with #582A72 as my main color, which is a nice
purple hue. Add the following code to theLinearLayout in the recently renamed splash_page.xml:
android:background="#582A72"
android:textColor="#BD1255"
We shouldnt blow our own trumpets, but this looks boss already
(http://cdn03.androidauthority.net/wp-content/uploads/2016/02/screen-3.png)
Only problem is, we still have the notification tray in a default blue color, which just does not go. So now youre going to open up
another file by using the explorer on the left. Under app > res > values youll find a file called colors.xml which is a handy resource
you can use to change the color palette of your app easily. If we had all the time in the world, wed be using this to file define all the
colors in the app and then referring back to it. This would make it much easier to change the color palette in future or to let the users
choose their own color scheme.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 9/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
Buuuut we dont have all the time in the world and for the sake of simplicity, were just going to enter color codes as and when we
need them. Your users will just have to make do with the one theme!
For this particular bit though, youre going to change the colorPrimary and colorPimraryDark elements to: #764B8E and #260339
respectively. For colorAccent, Im using #882D61. Youll notice that you can actually see a preview of the color pop up on the left
convenient!
(http://cdn03.androidauthority.net/wp-content/uploads/2016/02/screen-2.png)
One last thing to do, is change that font to something thats a little nicer. Unfortunately, its not even half as easy as it should be to set
custom fonts. So we wont worry about that.
android:fontFamily="sansserifthin"
Its a little more original and a little more minimal and it just looks cooler.
It still lacks a certain je-ne-sais-quoi however what it needs is a logo of some sort. I made this logo for us to use in Adobe Illustrator
using some of the other color codes we found in Paletton. It totally looks like a crystal. Shush.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 10/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn03.androidauthority.net/wp-content/uploads/2016/02/screen-4.png)
So were going to add this image to the drawable folder for our app project. This can be found at app > src > main > res > drawable.
The way I like to do it is to right click on the folder or file and then select Show in Explorer. This way, you can conveniently drag and
drop your files just as you would with any other folder.
So plop crystalize.png in there and then add an image view to your splash_page.xml, right beneath the ImageView. This will look like
so:
<ImageView
android:layout_height="60dp"
android:layout_width="wrap_content"
android:src="@drawable/crystalize"/>
This looks sort of cool, but really we want it to align vertically. So now add these lines to theLinearLayout :
android:gravity="center"
android:orientation="vertical"
While you are there you can also change layout_height for the image to 60dp. Now you should have a nice, somewhat pro looking
front page for your app.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 11/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn04.androidauthority.net/wp-content/uploads/2016/02/Screenshot_2016-02-11-13-34-21-16x9-1080p.jpg)
Thats why were going to let them tap anywhere on the screen to start enjoying the app.
android:onClick="onSplashPageClick"
publicvoidonSplashPageClick(Viewview){
finish();
}
Importandroid.view.View;
Until you do this, youll see an error crop up and the word View will be red. Android Studio should prompt you to do this automatically
though and if you place your cursor on the highlighted text, wait for the little dialog and then hit Alt+Return, you can generate the
necessary lines without any typing. Importing statements like this give us access to classes, thereby letting us use extra code in our
apps.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 12/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn03.androidauthority.net/wp-content/uploads/2016/02/screen-6.png)
If this is your first time coding java, then welcome! This is where well be defining the behaviour of the app, whereas the XML lets us
arrange our views and what theyre going to look like. You may already know this but when using java, every line ends with a semi
colon (unless its the start of a pair of curly brackets). If theres an error and youre not sure whats causing it, it may well be that you
forgot one of these semi colons somewhere.
Try loading up the app now on an emulator or on your phone. You should now find that touching anywhere on the screen causes the
app to close. This is the finish() line in action, which is triggered by the onSplashPageClick event that is called when you click on the
LinearLayout.
This tells us that our little bit of code is working but we have more ambitious plans in store for Crystalize!
Adding an activity
Rather than just closing this app, it would be good if we could open up the next page. To do this, were going to create a new Java file
and a new xmlfile to go along with it.
Right click on your package name in the file explorer (on the left) and then select New > Activity > EmptyActivity from the drop-down
menu. This will create another new activity just like our first one. Remember to choose empty activity again to keep things simple.
Were now going to call this new pagequestions, so follow the steps to create the java file as well as activity_questions.xml. This is
where were going to be displaying the questions (in case you hadnt guessed).
Once again, questions.java will control the behavior and activity_questions.xml will control the look.This is actually indicated by this
line in questions.java where the xml is referenced:
setContentView(R.layout.activity_questions);
If you changed that line to activity_main, then this page would have the same appearance as the first page!
For extra credit, check your AndroidManifest.xml file. Youll see that a section describing your new activity has been mentioned there.
The Manifest file contains important information about your app which is necessary for the Android OS as well as other apps (like
launchers) that are going to interact with us. You dont generally need to worry about it at this level but knowing its there is handy as it
will be important in future.
Now head back to MainActivity.java and swap finish() for this new line of code:
Intentintent=newIntent(this,questions.class);
startActivity(intent);
http://www.androidauthority.com/topandroidperformanceproblems666234/ 13/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
This is telling the app to start the next activity when the screen is clicked (instead of closing the app). Again, we need to add an import
statement and again you can do this by clicking on Intent and then pressing alt + return when instructed to. This should remove the
error messages.
(http://cdn02.androidauthority.net/wp-content/uploads/2016/02/screen-6-new.png)
Ive also set my activity_questions.xml to have a colored background likethe splash page, just so that things look as nice as possible
early on. Im using a lighter color from our color palette though because we need to be able to read text on top of it. So in the
activity_questions.xml, add the background for the layout again and change it to a linear layout again. Well alsoset the orientation to
vertical just like before:
android:background="#764B8E"
android:orientation="vertical"
Give the app a go though and you might find that there is still some less-than-ideal behaviour though. When we click the screen and
launch the next activity, this all works perfectly nicely. The only problem is that hitting back takes us back to the previous page and
shows us the splash screen again.This is not the behaviormost users expect from their apps!
So to eradicate this behavior, were going to put back the finish(); line in our onClick, just below startActivity(intent);. This will now
simultaneously start the new activity while also closing the old one, so that when you hit back from the second activity, it just closes
the application. Sorted!
Using views
Next, we want to populate the new activity with the relevant fields buttons, text boxes etc. In Android, these are called views and the
easiest way to add them is by editing thexml file. (You can also use the designer or add them programmatically via the java, but I think
this is the best method for illustrative purposes.)
Before we do this, were going to first add some info to the strings.xml file. This will come in handy in a moment. Youll find this in the
explorer at: app > res > values. Again, you may wish to diverge from my app here if youre trying to make a different kind of quiz or
test but these are the strings Im using:
<stringname="Q1">WhatistheletterAinthephoneticalphabet?</string>
<stringname="A1">alpha</string>
<stringname="H1">Atough,domineeringmale</string>
A string is a type of variable (a unit of data that you give a name) that in this case carries letters and words. We can define our strings
in this file and then refer to them throughout the rest of our code (just like the colors.xml). Here Ive added a question, the correct
answer and a hint.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 14/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn03.androidauthority.net/wp-content/uploads/2016/02/screen-7-new.png)
Now were going to edit the activity_questions.xml, which will set up the layout for this second activity.
Okay, youll want to hang on to your hat for this next part as were adding a lot of code! If you remember how we managedthe
TextView and ImageView in splash_page.xml, were basically repeating that same process here with more views. Now we have a text
view, an edit text and two buttons. Were also adding a bit more information to help keep things laid out nicely. Copy out this code and
youll notice a pretty simple pattern emerging for adding views:
http://www.androidauthority.com/topandroidperformanceproblems666234/ 15/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sansserifthin"
android:textColor="#440027"
android:textSize="30dp"
android:layout_marginTop="100dp"
android:text="@string/Q1"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#9775AA"
android:inputType="text"
android:textSize="20dip"
android:layout_margin="10dp"
android:hint="Answer"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Okay"
android:layout_margin="2dp"
android:padding="2dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:layout_margin="2dp"
android:text="Hint"/>
</LinearLayout>
This is going in-between the first linear layout (remember we changed it from relative to linear in the last section), so the top of the
page should look like this:
http://www.androidauthority.com/topandroidperformanceproblems666234/ 16/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
(http://cdn01.androidauthority.net/wp-content/uploads/2016/02/nest-linear-layouts.png)
The text for the TextView notice is @string/Q1, which is referencing the Q1 string we added just a moment ago. If youve done this
right, AndroidStudio should recommend the strings you have available as you start typing.
(http://cdn04.androidauthority.net/wp-content/uploads/2016/02/screen-8-new.png)
http://www.androidauthority.com/topandroidperformanceproblems666234/ 17/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
Notice how we have two separate linear layouts at this point. These are now nested and it means we can have a row of buttons going
horizontally and stack them underneath our other vertical elements (notice the orientation is defined as horizontal this time). Weve
also added lots of padding and margins to space everything out. Padding is how much space you want within the view, whereas the
margin is how much space you want to leave around it. android:hint meanwhile is the faint text that shows before the user starts
entering anything.It all should give you something that looks like this in the designer:
(http://cdn01.androidauthority.net/wp-content/uploads/2016/02/screen-9-new.png)
To do this, were adding an onClick to our button and an ID to our edit text in the activity_questions.xml. The button gets:
android:onClick="onAnswerClick"
android:id="@+id/answer"
android:onClick="onHintClick"
Now comes the tricky part: adding the actual code to define the behavior in the app. At this point you should know what that means,
opening up the java! So head over to questions.java. There are a few new concepts well need to introduce at this point, so lets start
with the easy bit: the Hint button.
For this, we want to use our onHintClick because as youll recall, this code runs whenever the specified view is clicked. Underneath
that, well also be adding another line of code, so input the following:
publicvoidonHintClick(Viewview){
Toasttoasty=Toast.makeText(getApplicationContext(),getString(R.string.H1),Toast.LENGTH_SHORT);
toasty.show();
}
As you go, remember to import the classes as you are prompted to do so.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 18/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
First of all, we are creating a toast message and calling it toasty. A toast message is a small dialog that pops up on the bottom half of
the screen and then disappears after a short while. We are filling this toast message with makeText and this requires us to add some
extra information about how that text is going to look and behave. The first item (getApplicationContext()) is the context and not
something you need to worry about at this stage. The second item (getString) is where the message you want to show goes. You could
just put Hello! in here for a greeting but in our case, were getting the string from strings.xml. Remember we called one of those
strings H1? So getString(R.string.H1) refers to that. Finally, Toast.LENGTH_SHORT just means the message doesnt hang around too
long.
Try running your app again and you should find that now, when you click on the Hint button, a little message comes up and says A
tough, domineering male, reminding us that the answer is indeed Alpha.
Now you grasp that bit, we can add our onAnswerClick as well.
publicvoidonAnswerClick(Viewview){
Stringanswer=((EditText)findViewById(R.id.answer)).getText().toString();
Stringcorrectanswer=getString(R.string.A1);
if(answer.equals(correctanswer)){
Toasttoasty=Toast.makeText(getApplicationContext(),"Right!",Toast.LENGTH_SHORT);
toasty.show();
}else{
Toasttoasty=Toast.makeText(getApplicationContext(),"Nope!",Toast.LENGTH_SHORT);
toasty.show();
}
}
(http://cdn04.androidauthority.net/wp-content/uploads/2016/02/screen-10-new.png)
Once again, this code runs only when someone clicks on the answer, at which point we create two strings: answer and correct
answer.
Answer is the string that the user entered and were getting this from the EditText using findViewByID. Correctanswer meanwhile is
A1 from our strings.xml.
Then were using an IF statement to compare the two strings and ensure that they are the same. When you use if () { }, the rest of
the code contained in the following curly brackets only runs if the statement in the regular brackets is true.
http://www.androidauthority.com/topandroidperformanceproblems666234/ 19/20
18/2/2016 TopAndroidperformanceproblemsfacedbyappdevelopers|AndroidAuthority
In this case, were showing our Right! toast message only if the answer the use gave is the same as the correct answer. If we were
using numerical variables, then we could say if (x == y) {, but with strings you have to do things slightly differently so we say if
(answer.equals(correctanswer)) {.
Right after the brackets close we have an else statement. This is what runs if the if () statement is untrue. This might all sound quite
familiar if youve used Excel equations. Run this bit of code and youll find that the toast message tells you if you have the answer right
or not.
Theres just one problem, which is that you can confuse the app by using upper case. As such, were also going to add one more line of
code right after we create our answer string. That is:
answer=answer.toLowerCase();
What youre doing here is simply converting the string to lower case. That way, it doesnt matter if the user decided to capitalize their
first letter or not.
Next time
Okay, I think thats probably more than enough for one day. Hopefully, your brain isnt swelling up too much at this point and youve
found some of this helpful, useful or interesting. You actually have enough of a basic understanding at this point to release an app of
your own if you want to. You could make a quiz for instance by starting a new activity every time someone gets the answer right and
then packaging it as a Christmas Quiz. Or you could make some kind of image quiz.
Thats obviously not the most effective way of making a quiz though and its not the most exciting of apps
So stay tuned for part two and well continue refining this thing and adding some cool features. Well start by tidying a few things up
and talking about the Android app life-cycle and from there, we can begin adding more functionality; letting users create their own
questions for instance and selecting which ones show uprandomly from a string array.
Or maybe theres something in particular youd like added? Let me know in the comments if theres something you want to see and
depending on what it is, we might be able to include it in the finished app.
Meanwhile, have a play with this app yourself. You can find all the files and resources at the GitHub repository here
(https://github.com/treehousefrog/Crystalize-Part-1).
LOAD COMMENTS
http://www.androidauthority.com/topandroidperformanceproblems666234/ 20/20