Android How-To: Card Flip Animation in API 23

Hello!

Lots of android devs are using this tutorial from the Google documentation to try to achieve a card flip animation, and they’re getting errors, including this one:

 05-22 11:32:34.706: E/AndroidRuntime(6801): java.lang.RuntimeException: Unknown animation name: objectAnimator

There does not appear to be a definitive answer that I can find as to how to get this to work. I got it. This is the relevant portion of my build file:

You’ll notice that I mention this library in the build. I downloaded it, rather than access it on bintray, to hedge against changes in its availability, and put it in the build/libs directory of my app.

When I go to flip in/out the child fragments, my parent fragment has this click listener on my flip button:

If you’re been banging your head against this (like I did at first), please pay it forward and share this with another Android dev who might like to know.

Test-Driven Android: Testing Multiple Cursor Loaders for One Activity/Fragment

I’ve found some favorite resources on writing Android apps. One of my favorites is Virgil Dobjanschi’s Google I/O Talk on Android apps as REST clients. This talk is relevant to every business-related app I’ve ever built, because most apps, on a general level, solve a lot of the same problems. Fetching data from an API and displaying it on the app is one of those problems. How many apps that I’ve built have demanded this functionality? All of them.

Virgil describes a couple of different levels of advancement for fetching and displaying data in an Android app. Lately, I have favored the most advanced one: making a call with a service, sticking the results in a database, and accessing them with a content provider and cursor loader to display on the UI.

Lots of tutorials will help you implement this pattern…on the simplest level. But what happens when, say, you have multiple tables, and you want to register updates for all of them on the same UI? If your LoaderCallbacks implementer is pulling from multiple databases, then your onLoadFinished() method has to distinguish between different CursorLoaders for each of your databases. And if the generic type for any of the CursorLoaders is the same, then you need to distinguish between them from within one onLoadFinished() method—because you can’t implement that method twice with the same signature.

Everyone on StackOverflow describes one of two solutions.

1) Implement two separate onLoadFinished methods and change one of the Loader’s generic types to not-a-cursor for the express purpose of loading them both in one activity/fragment. This works by adding a layer of indirection that can make the code confusing for developers who are unfamiliar with the pattern.

2) rely on the loader ID, which makes total sense, and works for the implementation code. The problem comes, as it frequently does with mobile development, when you try to unit test this approach. When we call onCreateLoader() from a test, the loader id does not get set. 

Seriously, take this code:

Print the loader.getId() for the loader that gets returned when you call onCreateLoader() in your tests. It will be zero in both cases, despite the fact that we expect the ids to be 1 and 2.

So what to do? I spelunked through the CursorLoader code a little and found a method that sets the id on the CursorLoader: registerListener(int id, OnLoadCompleteListener<Cursor> listener).

So when we add this call to our onCreateLoader() method, we get this:

and that sets the loader id!

So now you can have a clean switch case in your onLoadFinished() method:

If you have been banging your head against this (as I did at first), please pay it forward and share this post with another Android dev who might like to know.

 

If I had a quarter for every time I have seen this damn dagger error…

Caused by: java.lang.IllegalArgumentException: No inject registered for {path.to.SomeClass}. 
You must explicitly add it to the 'injects' option in one of your modules.

Let’s be honest: this error is the hazing of Android development with Dagger*. My colleagues and I have spent oodles of time trying to figure out why we are getting this.

We are not alone, if the litany of StackOverflow questions and other internet hits for this error is any indication.

*Clarification: this article is specific to Dagger 1.2, the version of Dagger written and maintained by Square. Dagger 2, maintained by Google, is not a later version of 1.2—it is a completely different version by a different team, and it works fairly differently to Dagger 1.2.

This post is an attempt to lead you, step by step, out of the clutches of this infuriating error. Given the number of reasons that you could be getting this error, the first few drafts will probably be incomplete. If this post does not help you resolve the error and you figure out how to resolve it by some other means, please e-mail me (chelsea at chelseatroy.com ) and let me know how you did solve the issue, so I can update this post to help the next person who ends up in your permutation of this problem.

Continue reading “If I had a quarter for every time I have seen this damn dagger error…”

Test-Driven Android: Tab Layouts

Tab layouts indicate that there are multiple pages to look at, and users can swipe them or click them to move from page to page.

tabs

Their implementation makes them difficult to test drive, so in this post we will go over how to do it.

We implement the tabs in Android by placing a TabLayout element in our activity’s view, then getting ahold of it in the Activity class code and adding tabs to it. There are limited ways to get an instance of TabLayout.Tab, and because it is a final class, it cannot be mocked.

Continue reading “Test-Driven Android: Tab Layouts”

Test-Driven Android: When and How I Use Robolectric

I’ll call this post “When and How I Use Robolectric” instead of “When and How to Use Robolectric” because a) I don’t like telling people when and how to do things, and b) I use Robolectric less liberally than most developers who use it.

Robolectric is a fantastic tool for ensuring that stuff in your Android app works properly. The problem, as you may have heard me say before, is that it runs slowly. In particular, FragmentTestUtil’s operations are especially time-expensive. Compounding the issue, Robolectric 3.0 currently has a memory leak that causes the heap to get bigger than it should. You won’t notice it on a smaller app, but when the app grows enough for the test suite to hit 600 or 700 Robolectric-assisted tests, the suite will hang or stop running because it runs out of memory before it completes.

So you only have 600-ish Robolectric bucks in the bank, and you spend one every time you write a test with Robolectric. My team at work, and I at home, have experimented with ways to save our Robolectric bucks. The first (main) trick has been to separate as much logic from the Android framework as possible and test that logic with JUnit. We save our precious Robolectric bucks this way, spending them on just a test or two for the places where the logic gets wired into the Android app.

Continue reading “Test-Driven Android: When and How I Use Robolectric”

Test-Driven Android: Testing Context-Dependent Components with a Provider

It’s much easier to write a test-driven application when we can isolate the class under test, so its tests fail as a result of its behavior and not the behavior of its dependencies. Exercising the dependencies in tests—whether they’re collaborating classes or entire frameworks—increases the number of reasons that a test might be failing, which limits how helpful that test can be in diagnosing issues and driving out an implementation.

In Android, there’s an additional concern: exercising the Android framework in tests is slow. So it makes sense to exercise the framework as little as possible in tests. This gets complicated when we consider the way the Android framework is built, though. First of all, it works chiefly by allowing us to subclass Android classes and override life cycle methods. This is not a recipe for easy dependency injection. Furthermore, idiosyncratic implementations of Android sometimes involve obtaining dependencies (like views from the layout) via a method besides injection. (We talk about how to test dependencies in that scenario in this post).

But there’s another catch to decoupling and testing in Android: the launching of some components depends on passing in other components.

Continue reading “Test-Driven Android: Testing Context-Dependent Components with a Provider”

Test-Driven Android: Separating Dagger from Robolectric in Test Suites

I test-drive Android apps with some help from the Robolectric testing framework. I also get some help (usually) from the Dagger dependency injector for employing dependency injection in those apps. I define modules in dagger for injecting classes into objects that depend on them, and I define test modules that inject mock versions of those classes when I write automated tests for the objects that depend on them.

As I learned more of the Robolectric and Dagger syntax over time, I could test-drive Android app features faster and faster. I did have an issue, though; in order to inject dependencies in Android, I needed a context. The Context object in Android provides information about the application environment, and it enables app-specific stuff like launching activities and sending/receiving broadcasts.

Continue reading “Test-Driven Android: Separating Dagger from Robolectric in Test Suites”

Test-Driven Android: Testing Layout Elements with Subclass and Override

There are a lot of reasons to write well-tested code: to drive software design decisions, to document the existing system, or to create a safety harness for confidently executing changes and refactors. But the Android framework (like most mobile and web frameworks) does not always lend itself to easy unit testing. Today we’ll talk about one particular case: the one in which you want to test that a method call on a view object that gets instantiated in the layout for an activity or a fragment.

Continue reading “Test-Driven Android: Testing Layout Elements with Subclass and Override”

Blog at WordPress.com.

Up ↑