From Punched Cards to Prompts
AndroidIntroduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
Android will be 10 years old this year and the team at Google introduced plenty of new updates at
Google I/O on May 8th. These changes range from user-facing improvements to API updates that
developers will be able to take advantage of in the near future. If you weren’t able to attend I/O
this year or watch the
recordings on Youtube, I’ll recap some of
what you missed.
One of the most significant changes that will affect developers is to the support library. Google
is continuing to build opinionated libraries to help developers, especially new developers, answer the question
of how to architect their apps. To provide even more help, Google has consolidated these libraries
into a set called Android Jetpack. This set of
libraries is offered so you can mix and match them based on your app’s needs.
Two new libraries were introduced alongside the existing Jetpack libraries:
WorkManager and the
Navigation Architecture Component.
The WorkManager is a new API that is built to perform background work for you without requiring
extra effort to deal with the different Android API versions. It will pick the best implementation
for the particular device it is running on, from JobScheduler to FirebaseJobDispatcher to
AlarmManager, so you can just focus on what you want WorkManager to do, not how it should do it. It
also provides additional features, such as the ability to chain work together so they execute in an
order you specify, and it provides a mechanism to check the state of your tasks and query their
return values by using LiveData.
The Navigation Component is built to make it easier to add navigation to your apps. It provides a
graphical editor for specifying the flow of screens in your apps. It looks very similar to the
storyboards from XCode. The Navigation Component does seem to work better with a single Activity
architecture, where it performs the navigation by swapping fragments in and out based on what
screen the user needs to go to. It is possible to use it with a multi-Activity setup but it is a
little more work, so that is something to consider if you want to try it in your projects.
The Paging Library is now
version 1.0. This library makes it simple to load data into a RecyclerView, then load additional
items as needed. Keeping everything asynchronous is important since scrolling lists is one of the
easiest places to spot visual jank in an app. Luckily the paging library loads your app’s data in
the background to keep your UI looking smooth. You can load your data with this new API no matter
where your data is actually stored, whether it is on a local database or on a remote server.
One other big announcement is that Google is heavily refactoring the package names for their
support libraries. They are collecting them all under the
AndroidX package.
AndroidX stands for Android extension libraries, and it will be the home of the support libraries,
architecture components, and any future libraries added to Jetpack.
There were also a couple changes announced that aren’t specifically relevant to the support
library, but they have big ramifications for developers. These updates aim to keep the system more
secure and make sure apps are keeping current with newer version of Android.
One is that the Android framework is going to start disallowing calls to private APIs in the system. For now these calls
will result in a Toast and a log message saying that the API call is illegal. In the future the
system will throw an exception if you try to access them. However, the list of restricted APIs are
not yet set in stone. If you find that an API your app relies on is going to be made restricted you
can submit a bug to
request that the API remains available.
The last announcement was about the new
deprecation policy
going into effect later this year. Any new apps submitted to the play store after August of 2018
must target API 26 or higher. If the app does not meet this criteria then it will not be allowed on
the store. Updates to existing apps will be held to the same restriction as of November of this
year. Google aims to prevent apps from targeting older versions of the operating system so users
will benefit from the security and performance improvements of the new version. This version will
remain at API level 26 for now, but it will be bumped up periodically to keep up with new releases.
Along with the target version restrictions, apps that include native libraries will be forced to
include 64 bit versions of their libraries. 32 bit versions will also be allowed, but the app must
also include the 64 bit version. This will allow users on devices that support 64 bit to benefit
from the new library.
Another exciting announcement revolves around testing. The folks at Google recognized that writing
tests for Android apps is really hard, particularly because the different kinds of tests you write
(unit, integration, and end to end) require different kinds of setups and different tools. The cost
of learning all of these tools and maintaining the different types of tests is very large, and can
drive people away from writing tests altogether.
Included in Jetpack is a new Android Test library that aims to make testing more painless, no
matter what kind of test you are writing. Android Test includes the existing test libraries like
Espresso, includes new APIs and Kotlin support, and the same tools will be used for on and off
device tests. Google’s goal is to allow developers to write their tests once and run them anywhere.
The tests are broken up into several parts; scaffolding, given, when, and then. The scaffolding
includes any of the general setup for your tests. It has been expanded to include things like
InstrumentationRegistry for your on and off device tests. The given part is where you setup the
specific dependencies for your system under test. Activity JUnit rules have been rolled into
Jetpack, ActivityTestRule is now available for off-device tests, and the ability to drive the app’s
lifecycle will be added in the future. The when part is all about driving your functionality under
test. With Espresso 2 joining Jetpack you will be able to use its API to write your tests and they
currently have preliminary support for off-device tests. Lastly, the then section verifies the
results of your tests. New APIs will help reduce boilerplate by making assertions more readable,
both in code and in the failure messages they print to the console.
While the new Android Test library looks very exciting, Google is also dropping Project Nitrogen,
which will be open source later this year. Project Nitrogen is meant as a single entry point for
your Android tests, no matter what kind of test you are running. It manages setting up the
environment by installing any test artifacts, running your custom fixture scripts, prepping a
simulated or real device to run the tests on, and preps everything for execution. Hermetic tests
are a main goal of Nitrogen so it uses the Android Test Orchestrator to collect all of your tests and executes them while trying to minimize any state leakage.
The tests are run in separate process to try and minimize those impacts across your test suite.
Once everything has executed, Nitrogen collects all of your test results and offers a unified
reporting format that will help you track down your test failures and identify why they failed. It
will include the relevant Logcat output from your test, screenshots, and profiling data which will
help fix those tricky bugs.
One last change that is sure to be a hit with Kotlin users is the updates to the Mockito library.
Recent changes now allow you to mock final classes, which is great considering that Kotlin classes are final by default. This means you no longer have to mark your classes as open or make unnecessary
interfaces just for testing. Static function mocking will be supported in the future as well, along
with the ability to mock system created objects like Activities. This is one thing I’m really
looking forward to, and I’m excited to see what changes are made to support this kind of mocking.
Another welcome focus this year is on performance improvements, both user-visible and
developer-facing. All of these will come together for a better user experience in your apps and a
better device experience overall for Android users.
Google continues to focus on battery life improvements. Building off of existing
functionality like Doze and App Standby, the Android team is offering the system more fine-grained
control over what services apps have access to. They refer to this as ‘App Standby Buckets’.
Effectively the system will determine the level of access to things like jobs, alarms, and the
network based on how frequently and recently the user has used an app. If the user hasn’t used an
app in a long time then it is going to be restricted from making network requests and its jobs will
be deferred until it is no longer in standby. This will help preserve the user’s battery life since
these infrequently used apps will not be running in the background without reason. Users will also
have the option to manually restrict poorly behaving apps from the Settings app. This will provide
more control to users over their device experience, although I’m hesitant to believe that many
users will know about the setting and use it in practice. Still, it reflects well on the Android
team to continually improve the OS and provide users with a better experience.
Another big announcement involved the introduction of the
Android App Bundle. This is a new
way of packaging apps that will reduce the download size for your users, which will particularly
help adoption rates in emerging markets. The app bundle involves splitting up your app in two ways:
by configuration, and by feature.
The configuration APKs will generate separate versions of your app based on different device
configurations. This helps because typically the largest contributor to bloat in an app is the
resources. By splitting these up, the Play Store can just provide the configuration relevant to a
user’s device which helps save bandwidth. If the user changes something on their device that
requires a different configuration bundle, the device will automatically download it from the play
store as needed.
The feature APKs allow you to separate your application by features. This will allow users to only
download the features that they need, while still allowing the Play Store to download additional
features when they’re required. This seems like a natural continuation of Instant Apps, which are
supported with App Bundles. This will certainly be more work that the resource configuration split
but you will end up with more modular code, faster downloads, and better build times.
Developers will also see improvements on their side. Performance improvements have been made for
Kotlin code by optimizing ART, D8, and R8. Google have been working to add more nullability
annotations to Java APIs which means any Kotlin code that interfaces with it can take advantage of
the nullable types, without having to assume everything is nullable.
Android KTX aims to make development easier and more
concise with a set of common extension functions specific to Android development. While it doesn’t
add any new functionality to existing APIs it will certainly make those APIs more intuitive to use.
Last but not least are the system UI changes that Google announced, as well as the APIs we have for
supporting them. There is a new display cut out API, support for Slices, and new Actions.
No matter what you call it; a display cut out, a notch, or a unibrow, it looks like they are here
to stay at least for a little while. To respond, Google introduced a new API to help your apps know where it is safe to draw on a screen that has a cut out. There are a range of options you can use, from playing it safe and not drawing around the notch at all, to getting the exact bounds around it and drawing on the entire screen. You can also test your devices on a new notched emulator instead of buying a device just for the cut out.
The introduction of Slices is a big opportunity for apps to share their information with other
apps. Your app can provide content to display as well as hints for how to display it, and a
SliceHost will be able to take that data and show it to the user. It’s also meant for more than
static content as well. User should be able to interact with the UI to accomplish their tasks
easily, no matter where they are.
Actions provide a way for users to take specific actions in your app, rather than just going to a
particular place. We can think of these like deep links with extra information about what the user
wants to do, such as play a particular song on Spotify, or make a reservation at a particular
restaurant on OpenTable. Actions also integrate with the assistant so users will be able to control
your app while interacting with the assistant.
The Android team has shown a continual commitment to improving the platform for everyone that uses
it, both the end users with their Android devices, to developers who help make the ecosystem so
vibrant. Google I/O 2018 has proven to be no exception. There are plenty of new APIs to experiment
with that will be keeping us all busy in the coming months. Be on the lookout for more blog posts
coming soon that dig deeper into these topics, and if you have any questions please feel free to
comment below. Thanks for reading!
Introduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
Jetpack Compose is a declarative framework for building native Android UI recommended by Google. To simplify and accelerate UI development, the framework turns the...
Big Nerd Ranch is chock-full of incredibly talented people. Today, we’re starting a series, Tell Our BNR Story, where folks within our industry share...