Learning Android with RubyMotion - Chapter 3
This is part of series of posts in which I work through the book Android Programming: The Big Nerd Ranch Guide. by Bill Phillips and Brian Hardy, and write the coding exercises with RubyMotion instead of Java. If you’re just jumping in, you may want to look over the introduction to the series to get yourself oriented.
Welcome to Chapter 3! This chapter gets into the nitty gritty of the Activity lifecycle, and starts with a discussion about logging.
Logging in Android
This first section of this chapter describes how to write to Android’s shared system-level log.
For basic console output while working in RubyMotion, the system log may be more than what you need. The venerable
p method will write output to the console just as it does in regular Ruby, and in many cases, this will be enough as you’re writing and debugging your app. But since we’re trying to learn The Android Way, let’s try playing with the Android log, just so we know our way around.
Log.d method as shown in the book is a little verbose in RubyMotion, so let’s wrap it in a method:
def debug(message) Android::Util::Log.d("QuizActivity", message) end
We’ll use the name of activity as the
TAG in the log entry. Why do we need the tag? You’ll see in a moment.
Now that we’ve got a nice, easy-to-use logging method, we can override one of the lifecyle events and log it:
def onStart super debug "onStart called" end
Now run the app, watch the console for your log message, and you’ll see…nothing.
This is because the RubyMotion console shows the output from the RubyMotion runtime, not the Android system log. The book shows you how to view the system log from within the IDE, but since we’re not using that, we’ll need to use the command line.
The command for viewing the Android log is:
(assuming that you have
adb in your
$PATH. If not, the full path is
Run that command, and behold the insanity. This is the system-level log, so it’s getting messages from everything running on the device (or emulator). We need a way to narrow the firehose. This is where our log tag comes in.
The documentation for the
logcat command has all the details on the various ways you can configure and control the log output, and you experiment with that to your heart’s content. For now, let’s try this:
adb logcat QuizActivity:D \*:S
This essentially says “show me all of the debug-level messages that have the tag ‘QuizActivity’, and shut everything else up”. If you run this command, you should see the “onStart called” message that you didn’t see the last time you ran the app.
Now you’re ready to log the rest of the lifecyle events as the book suggests, and see how they appear when you launch, pause, and stop your app.
Fixing a Bug
As the book points out, we have a bug. When we rotate the device, we lose the question that we’re currently on because we need to save our current state before rotation. We’ll fix that bug in this section.
First, create a new
layout-land subdirectory under
resources and add the code described in Listing 3.4 to create a landscape view for GeoQuiz.
Next, we need to override
onSaveInstanceState to stow away the value of
# a key for storing the current index KEY_INDEX = "current_index" ... def onSaveInstanceState(saved_instance_state) super debug "onSaveInstanceState" saved_instance_state.putInt(KEY_INDEX, current_index) end
And finally, we need to look for that value in
onCreate and use it as the current index if it’s available. Add this somewhere in your
if saved_instance_state @current_index = saved_instance_state.getInt(KEY_INDEX, 0) end
Launch the app, hit the “Next” button a couple of times and rotate the device - now the question sticks after every rotation. Our first bug is fixed! Hopefully, they’ll all be just as simple. (Hey, I can dream, can’t I?)
That’s all for the main coding examples in this chapter. The rest of the chapter has some really good info about how Android saves and restores activities, and some more info about logging, so be sure to read through all that carefully.
See you soon for Chapter 4.comments powered by Disqus