Running and testing an app
There are an enormous number of Android devices available today, and they come in a huge variety of shapes and sizes. As developers, we want our applications to run on as many devices and form factors as possible, and we want to be able to do it with the minimum of coding. Fortunately, the Android platform is well suited to this challenge, allowing us to easily adapt layouts and to construct virtual devices to match any form factor we can imagine.
Tip
Google provide a very handy cloud-based app testing facility at firebase.google.com/docs/test-lab/
Obviously, virtual devices form an essential part of any testing environment, but that is not to say that is not very handy to simply plug in one of our own devices and test our apps on that. This is not only faster than any emulator, but as we shall see now, very simple to set up.
Connecting to a real device
As well as being faster than virtual devices, actual devices also allow us to test our apps in real-world situations.
Connecting a real device to our development environment requires two steps:
- Enable developer options on your handset. On some models, this can involve navigating to
Settings | About phone
and tapping onBuild number
seven times, which will then addDeveloper options
to your settings. Use this to enable USB debugging and to Allow mock locations. - It is more than likely that you will now be able to connect your device to your workstation via a USB or the WiFi plugin cable and for it to show up when you open Android Studio. If not, you may need to open the SDK Manager and install the Google USB driver from the Tools tab. On some rare occasions, you may have to download a USB driver from the device's manufacturer.
A real device can be very useful for quickly testing changes in the functionality of an app, but to develop how our app looks and behaves on a variety of screen shapes and sizes will mean that we will create some virtual devices.
Connecting to a virtual device
Android virtual devices (AVDs) allow developers to experiment freely with a variety of emulated hardware setups, but they are notoriously slow, can exhaust the resources of many computer systems, and lack many of the features present in actual devices. Despite these drawbacks, virtual devices are an essential part of an Android developers' toolkit, and by taking a few things into consideration, many of these hindrances can be minimized:
- Strip your virtual device down to only the features your app is designed for. For example, if you are not building an app that takes photos, remove camera functionality from the emulator; one can always be added later.
- Keep the memory and storage requirements of the AVD to a minimum. Another device can easily be created as and when an app needs it.
- Only create AVDs with very recent API levels when you need to test for specifically new features.
- Begin by testing on virtual devices with low screen resolution and density. These will run much faster and still allow you to test for different screen sizes and aspect ratios.
- Try separating very resource demanding functions and testing them individually. For example, if your app utilizes large collections of high-definition images, you can save time by testing this functionality separately.
It is generally quicker to construct virtual devices to suit specific purposes rather than an all-purpose one to test all our apps on, and there is a growing number of third-party Android emulators available, such as Android-x86 and Genymotion, that are often faster and have more development features.
It is also worth noting that when testing for layouts only, Android Studio provides some powerful preview options that allow us to view our potential UIs on a wide number of form factors, SDK levels and themes, as can be seen in the next image:
For now, create a basic AVD to run and test the current project on. There is nothing really to test, but we are going to see how to monitor our app's behavior during runtime and how to use the debug monitor service to test output without having to use the device screen, which is not an attractive way to debug a project.
Monitoring devices
The following demonstration works equally well on either an emulated device or a real one, so select whichever is easiest for you. If you are creating an AVD, then it will not require a large or high density screen or a large memory:
- Open the project we just worked on.
- From the
Tools | Android
menu, enable ADB Integration. - From the same menu, select Android Device Monitor, although this may well already be running.
- Now run the application on your connected device with the Android Monitor.
The Device Monitor is useful in several ways:
- The Monitors tab can be used during runtime to view live system information such as how much memory or CPU time our app is using. This can be particularly helpful when we want to see what resources our apps are using when they are not running in the foreground.
- The monitor can be set to collect a variety of data, such as method tracking and resource usage, and store these as files, which can be viewed in the Captures pane (which can usually be opened from the left-hand gutter).
- Screenshots and videos of an app in action are very simple to capture.
- LogCat is a particularly useful tool as it not only reports live on an app's behavior, but as we will see next, can also generate user-defined output.
Using a text view to test our factory pattern is a convenient but clumsy way to test our code for now, but once we start developing sophisticated layouts, it would soon become very inconvenient. A far more elegant solution is to use debug tools that can be viewed without affecting our UIs. The rest of this exercise demonstrates how to do this:
- Open the
MainActivity.java
file. - Declare the following constant:
private static final String DEBUG_TAG = "tag";
- Again, you may have to confirm the importing of
android.util.Log;
. - Replace the line in the
onCreate()
method that sets the text of the text view with the following line:Log.d(DEBUG_TAG, bread);
- Open the Device Monitor again. This can be done with Alt + 6.
- From the dropdown in the top-right of the monitor, select Edit Filter Configuration.
- Complete the resultant dialog, as seen here:
Running the app and testing our factory demo should produce an output in the logcat monitor similar to the one seen here:
05-24 13:25:52.484 17896-17896/? D/tag: Brioche 05-24 13:36:31.214 17896-17896/? D/tag: Baguette 05-24 13:42:45.180 17896-17896/? D/tag: Roll
Tip
You can, of course, still use System.out.println()
if you like, and it will print out in the ADB monitor, but you will have to search for it among the other output.
Having seen how we can test our apps on both real and virtual devices and how we can use debug and monitoring tools to interrogate our apps during runtime, we can now move on to a more realistic situation involving more than a single factory and an output more sophisticated than a two-word string.