My little Android warehouse

Random thoughts about my experience as moonlight android developer.

Android, MVP, Dagger and Testing

MVP is Model View Presenter

.. which is a pattern that is very popular among Android developers nowdays.

I don’t intend to write (yet) another guide about MVP in Android, because others have done a better job, for example:

A lot have been said about MVP (and other similar patterns), like:

  • it isolates the business logic from the UI
  • it makes faster and easier to unit test the business logic
  • it avoids having a god Fragment or Activity class that manages everything
  • it makes it easier to maintain the app

However, the first thing you notice while switching into “MVP mode”, is a great sense of order.

In all the (few) apps I wrote before, I ended up with the well known hodgepodgey fragment or activity that contained both the UI logic and the business logic.

By defining the responsabilities of the view and of the presenter with MVP, you implicitly define the interfaces between those two components (and the model), and everything fits its place.

Every touch, drag, and eventyally lifecycle events are just events that are reported back to the presenter, which then chooses what to do with them. This is powerful.

This post is about my experience with the MVP pattern, Dagger (2) and testing.

Given the definition of the interface between the view and the presenter, I ingenuosly expected that testing of both (using unit tests and Espresso tests) would have been super smooth. As it often happens, the reality is quite different from what one expects and reads from blogs. In this post I will try to sum up all the issues I had during that process and the solutions I tried to put in place.

In order to better illustrate the concepts, I wrote a little example that can be found on my github repo

The structure of the app is the same one the can be found googling for Dagger / MVP , for example here.

The only thing I added is a local component / module that I use in order to inject the stuff needed only by that particular set of classes.

This means that in addition to the global Component / Module classes, used to inject stuff like the storage, there will be a local Component / Module used, for example, to inject the presenter into the View.

The easy part: testing the presenter

The dependencies are resolved by passing what it needs as constructor parameters:

1
2
3
4
5
6
@Before
public void setup() {
    mMockView = mock(MainView.class);
    mMockStorage = mock(KeyValueStorage.class);
    mToTest = new MainPresenterImpl(mMockView, mMockStorage);
}

Since no injection magic is involved here, we can just mock the view and all the other stuff the presenter needs and easily write unit tests for a Presenter instance.

Moreover, all the dependencies with external models / sources of data like retrofit can be tested by testing the behaviour of the presenter.

The “I expected it to be easier part”: testing the view

A common approach I heard around is to test the view not against a mock presenter, but against a presenter injected with mocked “external components”, such as api client and storage.

What I wanted to achieve here on the other hand, is to test the view driving the behaviour of the presenter it interacts with.

With this strong separation of roles, I expected it to be easy to mock the presenter and test the view with Espresso.

Injecting a mock presenter

Since the presenter is provided by the local module and injected into the view by Dagger, I had to find a way to override the Module in order to provide the mock presenter that could drive the tests.

By using the common method to inject the view

1
2
3
4
DaggerMainComponent.builder()
            .applicationComponent(app.getComponent())
            .mainModule(new MainModule(this))
            .build().inject(this);

the only way to override the presenter since it is provided by the “real” MainModule is to use build flavours, as shown in Android testing codelab.

However, I wanted to take advantage of Dagger 2 injecting a mock presenter.

The key of replacing a dependency is by overriding the Application object

By adding a factory method that returns an istance of the module in the Application class

1
2
3
4
DaggerMainComponent.builder()
                .applicationComponent(app.getComponent())
                .mainModule(app.getMainModule(this))
                .build().inject(this);

Then we can be use a custom test runner that provides a subclass of that application object declared in the Manifest.

1
2
3
4
5
6
7
public class EspressoTestRunner extends AndroidJUnitRunner {
    @Override
    public Application newApplication(ClassLoader cl, String className, Context context) throws
            IllegalAccessException, ClassNotFoundException, InstantiationException {
        return super.newApplication(cl, TestMvpApplication.class.getName(), context);
    }
}

and declare it in our gradle file

1
2
3
4
5
6
7
8
android {
    ...
    defaultConfig {
  ...
        testInstrumentationRunner 'com.whiterabbit.windlocator.EspressoTestRunner'
  ...
    }
}

The Application object (and its test variant) is the one responsible of providing all the modules, so by subclassing it we can drive what is provided to be injected:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestMvpApplication extends MvpApplication {
    private MainModule mMainModule;

    // By usint this two method we can drive whatever module we want during the tests
    // (and with that, drive what classes inject)
    @Override
    public MainModule getMainModule(MainView view) {
        return mMainModule;
    }

    public void setMainModule(MainModule m) {
        mMainModule = m;
    }
}

This is what the setup method would look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Before
public void setUp() throws Exception {
    // a mock module with the mock presenter to be injected..
    MainModule m = mock(MainModule.class);
    mMockPresenter = mock(MainPresenter.class);

    when(m.provideMainView()).thenReturn(mock(MainView.class)); // this is needed to fool dagger
    when(m.provideMainPresenter(any(MainView.class), any(KeyValueStorage.class)))
      .thenReturn(mMockPresenter);

    Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
    TestMvpApplication app
      = (TestMvpApplication) instrumentation.getTargetContext().getApplicationContext();

    // forced to the application object
    app.setMainModule(m);
}

A mock module is needed to provide a mock presenter. Then the mock module is passed to the application object. Please note that in order to have Dagger 2 working, the mock module needs to provide a view instance (even a mock one) that will never be used.

Now we can finally write a test method:

1
2
3
4
5
6
@Test
public void testButtonClick() {
    activity.launchActivity(new Intent());
    onView(withId(R.id.main_button)).perform(click());
    verify(mMockPresenter).onButtonClicked();
}

After all this struggling, we can “just test the view”, meaning that we do not need to test if the mocked rest end point was called, nor if the storage was asked to write something. We just test the view against the presenter interface

One piece is still missing: what if we want to test the behaviour of the view when one of its methods gets called by the presenter? In the example, the view interface offers a method to set the text displayed.

Again, one could naively think that it would be sufficient to call the method with something like

1
activity.getActivity().showValue("23");

The truth is, espresso tests run in a thread different from the UI thread. By doing that, it would result in

Only the original thread that created a view hierarchy can touch its views

One way to overcome this, is to call the methods in the ui thread

1
2
3
4
5
6
activity.getActivity().runOnUiThread(new Runnable() { // fancy using a lambda here?
                                                 @Override
                                                 public void run() {
                                                     activity.getActivity().showValue("23");
                                                 }
                                             });

Why I did not use the @UiThreadTest annotation?

Simply because it would have ended with another exception since startactivity cannot be called directly from the ui thread.

To sum up

  • Make the application provide the Module that provides the presenter(s)
  • Change the testrunner in order to provide a different application
  • Let the “test” application provide a mock module that provides a mock presenter
  • Test!

Conclusion

The Mvp pattern isolates the view (which needs to be as dumb as it can) from the presenter. By instrumenting the view with a mocked presenter, you will drain those tests from any kind of logic we expect to be in the presenter. You just test that the interface between the presenter and the view is working as expected.

By doing this, you can focus on testing the business logic inside the presenter with vanilla unit tests. Your tdd loop will definetely be faster.

A big thank as always to my proofreaders Fabio Collini & Riccardo Ciovati!

Reactive Android Timers, Countdowns and Lifecycle

Ok, I must confess

the title is built to draw people’s attention, because you know, nowdays everything is done in a reactive fashion. RxJava is superhelpful, but if we forget the ecosystem our apps are running into, we risk to forget the proper way to implement certain tasks in Android.

Why do we need a whole post about timers?

Recently, I had to implement a countdown timer in Android.

If you google for code to cut and paste inspiration, you’ll get a lot of results like:

There is even a cookbook recipe that shows how to implement it.

That might work if you had to measure the cooking time of a portion of capellini (the fastest cooking pasta I could think of).

But wait, what if I had to bake a plum cake?

Baking a plum cake takes longer than an hour. All the solutions I just mentioned rely on the fact that your application is running for the whole lenght of the timer.

This could be acceptable in the desktop / server world, but it’s far from acceptable in the Android context: if the app goes in background because the user wants to check his email, answer to a phone call or play a game, the operating system is likely to reclaim the resources and shutdown the app itself. In any case, the device will turn off after a short time. If you think that using a wakelock will solve the problem… it will, but the user won’t be happy of all the battery wasted by the screen.

I can use a foreground service!

So one can start looking for a way to keep the app running in background. A Service is an Android component made specifically for this purpose.

By using a Service with the startForeground option, your app will stay alive through the whole lenght of the timer. When the timer is finished, it just has to throw a notification and a broadcast so the user will know that the timer expired.

This approach will work, but it has a drawback. Your app (or let’s say at least the service) needs to be running for the whole length of the timer. This is a waste of memory and cpu.

The right way

The right way is to take advantage of what the OS offers. The idea here is to run the countdown timer as long as the app is foregrounded, showing the progress to the user one second at the time, but set a system alarm whenever the app goes in background. Whenever the user gets back to the app, you’ll cancel the system alarm and restart the timer from where it is supposed to start.

Here what it would look like when the user gets back to the app before the timer is expired (on the left) and when the timer expires while the app is in background (on the right):

From the user’s perspective, the timer is running even if the app is in background, because whenever he returns to the app he sees what he is expecting to see (the time passed). On the other hand, if the timer expires when the app is in background, a friendly notification will remind him that he has to take the plum cake out of the oven.

Inside the app however, the timer will run only when the app is in foreground and has all the rights to consume cpu because the user is using the app.

Some code

A simplified version of what I am describing can be found in my github repo

There are three things you have to take into account:

Running the timer in the app

This is the easiest part: you can use a countdown timer, a handler, rxjava or whatever you want to copy and paste take inspiration from. In my example I’ll use a countdown timer since it’s simple to use and serves the purpouse.

1
2
3
4
5
6
7
8
9
10
11
12
13
private void startTimer() {
    mCountDownTimer = new CountDownTimer(mTimeToGo * 1000, 1000) {
    public void onTick(long millisUntilFinished) {
  mTimeToGo -= 1000;
  updateTimeUi();
    }
    public void onFinish() {
  mState = TimerState.STOPPED;
  onTimerFinish();
  updateTimeUi();
}
    }.start();
}

Remembering when the timer was started / how long it was supposed to run

This is the trickiest part. In the example I store the starting time inside the shared preferences storage. It will persist even if the app is killed.

1
mPreferences.setStartedTime(getNow());

That value is used when resuming the app in order to check how long the timer has to run (or if the time did expire):

1
2
3
4
5
6
7
8
9
10
private void initTimer() {
    long startTime = mPreferences.getStartedTime();
    mTimeToGo = (TIMER_LENGHT - (getNow() - startTime));
    if (mTimeToGo <= 0) { // TIMER EXPIRED
        mTimeToGo = TIMER_LENGHT;
        onTimerFinish();
    } else {
        startTimer();
    }
}

The app tries to retrieve the start time value. If there still is some time to run, the countdown restarts for the remaining length of time. Otherwise the timer is reset and the user is notified of the timer expiration.

Please note that this is a ultra simplified version that assumes that the timer is running. The github sample checks also if the timer was started or not.

Handling the alarm

This is simple. You should set the alarm that triggers a broadcast receiver through the alarm manager:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected void onPause() {
    super.onPause();
    long wakeUpTime = (mPreferences.getStartedTime() + TIMER_LENGHT) * 1000;
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, TimerExpiredReceiver.class);
    PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        am.setAlarmClock(new AlarmManager.AlarmClockInfo(wakeUpTime, sender), sender);
    } else {
        am.set(AlarmManager.RTC_WAKEUP, wakeUpTime, sender);
    }
}

and cancel it in onResume:

1
2
3
4
5
6
7
8
@Override
protected void onResume() {
    super.onResume();
    Intent intent = new Intent(this, TimerExpiredReceiver.class);
    PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    am.cancel(sender);
   }

Launching a system notification that brings the user back to the app when clicked is trivial. You can check the sample on github.

Conclusion

What I wrote today may sound obvious to a lot of experienced developers.

However, I thought it was a post worth writing since it’s a good example of how you should always remember the ecosystem your app is being run into. If you forget this and think that your app is the most important app the user has in his phone, you’ll face some unexpected behaviours (the app gets killed) or you will piss the user off (the app needs to be active for the whole length of the timer).

Thanks as always to Fabio Collini and Riccardo Ciovati for proofreading.

Happiness Is (a) Relative (Layout)

Using relative layout is bad

.. or at least they say so. The truth is, it is relatively easy to build complex layouts using RelativeLayouts, but this ease of use comes with a cost: in order to provide that kind of flexibility, RelativeLayout does two measurement passes.

There are a lot of talks and posts explaining that if you have nested relative layouts, you’ll end up with many measurement passes that will consume your cpu and will contribute to miss the dreaded 16 ms threshold. The higher the RelativeLayouts are placed in your view hierarchy, the more will be the number of measurements.

It’s easier than you think: let’s pretend you have a RelativeLayout as the root of your activity view (because hey, it’s what Android Studio sets as default from the BlankActivity template).

Then you have a fragment, and for some reason you have a list you want to place aside a button and you need a RelativeLayout over there.

Finally, you’ll have to place an image and a text inside the list elements, isn’t there an easier way than RelativeLayout? (Actually, there is and it’s much more efficient)

What will happen here is that with this unharmful scenario the onMeasure() method of each children of the list will be called 8 times each frame.

But why does RelativeLayout need two passes?

Given that Android is an open source framework, I could satisfy my curiosity by digging into the source code. Here I will try to provide a high level explanation of my understanding on how it works, without going too much into the details.

Let’s pretend you want four children (A, B, C, D) for your layout, and the rules are the following:

  • A is above C
  • B is to right of A
  • D is below B and its right margin is aligned to B
  • C is to left of D and its top is aligned to D

The concept behind RelativeLayout is fairly simple. In order to measure (and place) a certain child, you need to measure (and place) all the views that child depends on in term of relationship. For this reason, the first thing RelativeLayout does is to build a graph of dependencies between the children. Those dependencies determine the order in which the children are measured (i.e. first the views with no dependencies, then the views that depend only from the root, etc).

This explains the need for two measurement passes: the order the views need to be measured horizontally can be different from the order the views need to be measured vertically. In my example, A does not have any horizontal dependency but vertically it depends on the size and the position of C.

In the example, the sequence of measurement are:

Horizontal dimension: A -> B -> D -> C

Note that given the vertical size is not calculated yet, the views are temporarly assigned with the height of the parent view while measuring the horizontal sizes.

Vertical dimension: B -> D -> C -> A

Other than these two passes, RelativeLayout can also loop its children up to three other times to finalize their placement (for example for those that are aligned to the bottom of the parent in case of wrap content).

The position of the views is calculated during the measurement double pass. For this reason the onLayout() implementation is pretty trivial.

Finally, the dependency lists are cached, but those cached elements are invalidated whenever a requestLayout() happens. This, together with the fact that requestLayout() goes up to the root and is called on all the children is another reason for not having deep view hierarchy especially with RelativeLayouts.

Optimizing RelativeLayout

First of all, remember that you don’t always need to. If you are in the early stage of the development or under strict time constraints and you prefer the simplicity of use of RelativeLayout against performance then use it, just be aware of the implications. This small piece of technical debt might come back in the future to claim its price.

Measure twice and cut once (but remember to do that from time to time). Hierarchy Viewer is a convenient way to understand if your hierarchy is too complex and to see at glance what’s costing too much:

Probe by Lucas Rocha is also an effective tool to check if your views are getting measured too many times.

After that, if you realize that your view groups suffer from performance issues, the most efficient way to optimize is to write a custom viewgroup. It might look scary at first, but it’s just a matter of measuring and placing boxes knowing exactly where you want to place them and how their container looks like. This will flat your hierarchy and make it a lot more efficient.

I don’t want to write (yet another) tutorial on building custom viewgroups here since it will double the lenght of this post, but some good starting points are:

What’s the take home lesson

RelativeLayout is an awesome piece of software. It makes it super easy to describe complex scenarios without needing to do nasty nested linear layouts.

However from today, before placing it inside a view I will start thinking not only about the two passes, but also to all the hard work this complex piece of software needs to do behind the scene in order to offer me the flexibility I am used to.

The two measurement passes can be the biggest source of problems because of the risk of exponential explosion, but other than that there are a lot of computation and additional data structures involved in building (and maintain) those dependency lists, and a good amount of extra loops through the children needed to place them correctly.

Thanks to Riccardo Ciovati and Fabio Collini for proofreading this post.

Subscribe It While It's Hot: Cached Rest Requests With RxJava

Disclaimer:

In this post I am trying to cover a proper approach to a common problem. I am still in the process of wrapping my head around RxJava so what I write here might not be the best way to solve the problem.

Cached requests with RxJava

Lately I’ve been trying to develop a rest backed app using RxJava. I must admit that once you get in the proper mental mood, RxJava almost feels like cheating. Everything looks cleaner, multiple requests can be composed and manipulated easily, the StrictMode gets satisfied by observing on the ui thread and subscribing on a different thread, and all the nice things that can be read about how cool is RxJava with Android. What I could not find easily, was how to store the result of a request and be sure that even in case of no network, a cached content was available for the user, while still handling everything in a reactive fashion.

Caching vs non caching

Going straight from rest result to the UI is appropriate in many cases, for example when displaying the result of a search whose arguments are not predictable (think about Ebay, or Amazon where the user is looking for something different every time).

However, there are cases when the results fetched earlier are still significant and displaying them can improve the user experience significantly, compared to a spinning wheel or a white page. Those cases include your twitter feed, a local weather forecast that was fetched just 5 minutes before, or the list of the github repos of a given user.

Here you can see the difference between a non cached version and a cached version of the same activity:

For this reason I tried to figure out what could have been a clean way to cache the results of a request while keeping the flow in a reactive fashion.

The storage as the unique source of the truth

All reactive

If we want to cache the data while keeping everything inside the same subscription, things get a bit messy. The result of the request is thrown at the UI and the response is also stored in the storage. The UI subscribes from the storage too but checks which result came first and if the data is too old.

Cached

In this hybrid variant, the UI subscribes only to the storage, and a facade class wraps the storage and the subscription to the retrofit client that feeds the storage. Once the storage is filled with new data, the UI thread is automatically notified of every change.

In this scenario the observable acts as a hot observable, the first time it gets subscribed it emits the content of the storage, and any other change it might happen to it.

Talk is cheap, show me the code

A working example of the following code can be found in my github repo here To write this sample, I started from the abused Github apis which seems to power the 99% of the rest related examples. Sorry about that.

First there is the storage. I wrapped a SQLite helper (which I happily generated with my handy script) with a class that contains a PublishSubject which can be subscribed to and which we will notify when the insertion methods are called:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class ObservableRepoDb {
    private PublishSubject<List<Repo>> mSubject = PublishSubject.create();
    private RepoDbHelper mDbHelper;

    private List<Repo> getAllReposFromDb() {
        List<Repo> repos = new ArrayList<>();
        // .. performs the query and fills the result
        return repos;
    }

    public Observable<List<Repo>> getObservable() {
        Observable<List<Repo>> firstTimeObservable =
                Observable.fromCallable(this::getAllReposFromDb);

        return firstTimeObservable.concatWith(mSubject);
    }

    public void insertRepo(Repo r) {
        // ...
        // performs the insertion on the SQLite helper
        // ...
        List<Repo> result = getAllReposFromDb();
        mSubject.onNext(result);
    }
}

What we have here is the first piece of the puzzle: a storage that can be subscribed to. The concatenation is needed because we want it to emit the content of the storage as soon as it gets subscribed.

Then there is the facade class, where we get the observable from and to which we start a new update:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ObservableGithubRepos {
    ObservableRepoDb mDatabase;
    private BehaviorSubject<String> mRestSubject;

    // ...
    public Observable<List<Repo>> getDbObservable() {
        return mDatabase.getObservable();
    }

    public void updateRepo(String userName) {
        Observable<List<Repo>> observable = mClient.getRepos(userName);
        observable.subscribeOn(Schedulers.io())
                  .observeOn(Schedulers.io())
                  .subscribe(l -> mDatabase.insertRepoList(l));
    }
}

Note that everything happens far from the UI thread. This is because we are going to subscribe to the database observable as the unique source of truth.

Now, given that the observable is now hot, we can’t listen for its onComplete in order to stop any progress indicators we might put in place. What we need is another subject that can be bound to the update request, so here it is the new facade class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ObservableGithubRepos {
    // ...

    public Observable<List<Repo>> getDbObservable() {
        return mDatabase.getObservable();
    }

    public Observable<String> updateRepo(String userName) {
        BehaviorSubject<String> requestSubject = BehaviorSubject.create();

        Observable<List<Repo>> observable = mClient.getRepos(userName);
        observable.subscribeOn(Schedulers.io())
                  .observeOn(Schedulers.io())
                  .subscribe(l -> {
                                    mDatabase.insertRepoList(l);
                                    requestSubject.onNext(userName);},
                             e -> requestSubject.onError(e),
                             () -> requestSubject.onCompleted());
        return requestSubject;
    }
}

In the UI client (activity or fragment) we’ll need to subscribe to the storage in order to get the data and to the request observable in order to stop the progress indicators. An observable that emits the state of the pending request is returned every time an update is being requested.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mObservable = mRepo.getDbObservable();
mProgressObservable = mRepo.getProgressObservable()

mObservable.subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread()).subscribe(l -> {
                mAdapter.updateData(l);
            });

Observable<List<Repo>> progressObservable = mRepo.updateRepo("fedepaol");
progressObservable.subscribeOn(Schedulers.io())
                       .observeOn(AndroidSchedulers.mainThread())
                       .subscribe(s -> {},
                                  e -> { Log.d("RX", "There has been an error");
                                        mSwipeLayout.setRefreshing(false);
                                  },
                                  () -> mSwipeLayout.setRefreshing(false));

Please remember that the DbObservable is a hot one, so every time a call to updateRepo happens, the db will be fed with the result of the query and the ui will get subsequently notified.

SqlBrite

If all this wrapping seems too laboruous, the prolific guys from Square wrote SqlBrite which is a super generic database wrapper that was written for this same purpouse. I am sure it’s better and more battle field tested than the poor man’s version we can write by ourselves.

Conclusion

I don’t know if this is an healthy way to use RxJava. Maybe I ended up with this scenario only because I am not 100% confident with RxJava and I am putting some non rx-ness in the middle to better control it. Here we need to choose where to place the operators, since we can modify the flow that feeds the storage from the http client, or the flow that comes out of the storage itself.

In any case, having an unique source of truth seems more clear, and I feel that in this way it would be a lot easier to do stuff like prefetching, scheduling updates so the user is presented with fresh data (remember having your app work like magic?), checking if an update is worth to be done at all (such as displaying a 5 minutes old weather forecast) and stuff like that.

Thanks to Fabio Collini for spotting a lot of mistakes in the first draft of this posts, and to Riccardo Ciovati for proof reading it.

Unit Testing RxJava Observables and Subscriptions

Testing RxJava

While catching up with the latest Android novelties I could not ignore RxJava, which seems to grow in popularity between android developers.

If you just heard about it, and you want to get your feet wet, I really recommend Dan Lew’s Grokking with RxJava series as a starting point.

RxJava is asynchronous by nature, so unit testing it might seem a daunting at first, especially if you use that asynchronous interaction to test stuff. Luckily, RxJava (and RxAndroid) come with a couple of tools that will make our life a lot easier.

What to (unit) test

There are at least a couple of things you’ll want to test:

  1. You will want to test the observables, meaning not only the observables you built, but also the resulting composition of the various operators you may want to apply to them.
  2. Given a certain observable (or its mock), you will want to test how the rest of your application behaves while triggered by the subscription.

Testing the observables

Despite the fact that a subscription is asynchronous, there are (at least) a couple of ways to make the stream of your observable synchronous.

The first way is by using

1
ResultToCheck res = myObservable.toBlocking().first();

This works because toBlocking converts the observable to a blocking one, while first returns the first emitted element. The calling code will wait synchronously until the observer calls onCompleted().

The official way to test an observable is by using a TestSubscriber, an helper subscriber provided directly by the RxJava library. As with toBlocking, a test subscription is synchronous. Here you can find an example:

1
2
3
4
5
6
7
Observable<RubberChicken> obs = obsFactory.getObservable();
TestSubscriber<RubberChicken> testSubscriber = new TestSubscriber<>();
obs.subscribe(testSubscriber);

testSubscriber.assertNoErrors();
List<RubberChicken> chickens = testSubscriber.getOnNextEvents();
// Assert your chickens integrity here

TestSubscriber comes with a bunch of helper methods for testing, like specific assertions and other stuff. On top of that, its getOnNextEvents() method is blocking and will return all the emitted items as elements of a list. This is a neat way to test not only your observers, but also to check if the compositions you put in place are working as expected. That makes testing observables super easy.

Testing the subscription

Once your observables are in place, you will likely to be observing them on some thread, and subscribing them on some other thread. This will make it harder for us to test how our activity (or fragment) reacts to a triggered subscription.

RxJava (and RxAndroid) provide a way to override the schedulers exposed when Schedulers.io() or AndroidSchedulers.mainThread() are called. By replacing them with Schedulers.immediate(), your code will run immediately and you’ll be able to see its results.

The solution is a bit hacky, since we need to call reset() method before overriding RxJava’s schedulers, which is package protected. I took inspiration from Alexis Mas’ blogpost extending RxJavaPlugins class (there no need for that with RxAndroid):

1
2
3
4
5
6
7
8
9
10
11
package rx.plugins;

public class RxJavaTestPlugins extends RxJavaPlugins {
    RxJavaTestPlugins() {
        super();
    }

    public static void resetPlugins(){
        getInstance().reset();
    }
}

Registering a scheduler hook that provides a custom implemetation (Schedulers.immediate()) will end up in overriding the schedulers we are using.

As pointed out by Patrik Åkerfeldt in the comments, since the hooks are asked to provide a scheduler implementation during the initialization of the Schedulers class, we have only one chance to override the default schedulers. For this reason, there is no point in setting them up in the setup phases of all our tests.

The best place to override them once seems to be the TestRunner’s constructor.

The custom TestRunner will look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class RxJavaTestRunner extends RobolectricGradleTestRunner {
    public RxJavaTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);

        RxJavaTestPlugins.resetPlugins();
        RxJavaPlugins.getInstance().registerSchedulersHook(new RxJavaSchedulersHook() {
            @Override
            public Scheduler getIOScheduler() {
                return Schedulers.immediate();
            }
        });
    }
}

And this is how the setup() and teardown() methods will look like (here I am using robolectric but it makes no difference with AndroidTests):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RunWith(RxJavaTestRunner.class)
@Config(constants = BuildConfig.class,
application = TestRobolectricApplication.class)
public class SubscriberTest {
    @Before
    public void setup() {
        RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() {
            @Override
            public Scheduler getMainThreadScheduler() {
                return Schedulers.immediate();
            }
        });
    }

    @After
    public void tearDown() {
        RxAndroidPlugins.getInstance().reset();
    }}

    /* Your tests here */
}

As I already mentioned, you can inject the custom schedulers only once per test session. On the other hand, RxAndroidPlugins come with a reset method that will allow us to hook in different schedulers in different threads.

This, together with a non blocking observable (for instance by replacing your long taking observable with a mocked Observable.just()) will make our test synchronous.

In order to inject a mocked observable, we can override the Application object used by Robolectric, as described in my previous post here .

Bonus point: debugging

If the unit tests are not enough, and you want to check what is happening inside the chaining / transformation of the stream, you can set an ObservableExecutionHook that will be triggered when observables are being called:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   private void enableRxTrack() {
        RxJavaPlugins.getInstance().registerObservableExecutionHook(new DebugHook(new DebugNotificationListener() {
            final String TAG = "RXDEBUG";
            public Object onNext(DebugNotification n) {
                Log.v(TAG, "onNext on " + n);
                return super.onNext(n);
            }


            public Object start(DebugNotification n) {
                Log.v(TAG,"start on "+n);
                return super.start(n);
            }


            public void complete(Object context) {
                super.complete(context);
                Log.v(TAG,"oncomplete n "+context);
            }

            public void error(Object context, Throwable e) {
                super.error(context, e);
                Log.e(TAG,"error on "+context);
            }
        }));
    }

TL;DR:

  • Use TestSubscriber when testing how an observable (or a composition of observables) behaves
  • Mock your observable and override the default schedulers to test how the subscribing class works
  • Enable the tracking of your observables by registering an observable execution hook

A working example (rubber chickens included) can be found on my github repo.

References

Mocking With Robolectric and Dagger 2

Why robolectric

I’ve been a fan of robolectric since the old days, since when Android Studio was not an option and few developers embraced IntelliJ. I left it a bit behind after the introduction of Android Studio, since its support was far from optimal.

Things have changed, and after listening Corey Latislaw advocating its usage during this fragmented podcast episode I wanted to give it a spin. Even if there is a bit of debate over its usage, mainly because tests are performed against mocked objects instead of the real framework code, it is the fastest lane to your tdd cycle because tests are run on the local jvm instead of being packed in an apk, deployed on a device and run over there.

Dependency Injection

One really cool thing about robolectric 3.0 is the fact that you can override the Application object declared in your manifest with a custom one (which can inherit from your application’s one).

If you are using dagger (or dagger 2) and you are using the application as the source of dependency injection for your classes, this allow to easily replace your injected objects with mocks. You can even choose which mocks inject in the setup phase of your tests.

Let’s see an example:

Let’s say you have your application class that exposes all the injected objects in a Dagger 2 fashion, and that you are using it to inject classes in your activities:

1
2
3
4
5
@Override
protected void onCreate(Bundle savedInstanceState) {
    // stuff 
    ((MyApplication) getApplication()).getComponent().inject(this);
}

Now, if we can drive the component injected within our tests, the rest of the app would use them and (hopefully) behave in a way we expect, depending on our mocks instead of the real objects.

The dependencies are provided by a module:

1
2
3
4
5
6
7
8
9
10
11
@Module
public class ApplicationModule {
    // stuff

    @Provides
    @Singleton
    GitHubClient provideClient() {
        return new GitHubClient(mApp.getApplicationContext());
    }
    // .. Provides other stuff
}

GitHubClient is a Retrofit (2) powered client that helps to retrieve all the repos for a given user.

By using a test only application, we can provide a module from our tests.

Let’s see ApplicationModule’s mocked alter ego. Note that we can override only the dependencies that we want to mock:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MockApplicationModule extends ApplicationModule {
    List<Repo> result;
    // stuff

    @Override
    GitHubClient provideClient() {
        GitHubClient client = mock(GitHubClient.class);
        // mock behaviour
        return client;
    }

    public void setResult(List<Repo> result) {
        this.result = result;
    }
}

Now that everything is in place, we can use the mocked objects in our tests:

1
2
3
4
5
6
7
8
9
10
11
12
13
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class,
        application = TestApplication.class)
public class SampleTest {
    @Before
    public void setup() {
        TestApplication app = (TestApplication) RuntimeEnvironment.application;
        // Setting up the mock module
        MockApplicationModule module = new MockApplicationModule(app);
        module.setResult(mockedResult);
        app.setApplicationModule(module);
    }
}

From now on, the our tested activities will be injected with our mocked github client and we will be able to test their behaviour.

Quirks

Since the Test Application object is created before running the tests, a default application module must be provided, otherwise you’ll get a dreaded NPE while running your tests.

1
2
3
4
5
6
7
8
public class TestApplication extends MyApplication {
    @Override
    ApplicationModule getApplicationModule() {
        if (mApplicationModule == null) {
            return super.getApplicationModule();
        }
        return mApplicationModule;
    }}

moreover, the dependency graph is generally built inside the Application’s onCreate method. Given that we want to recreate it with our mocked module, I had to add a method for that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyApplication extends Application {
    // Stuff 
    @Override
    public void onCreate() {
        super.onCreate();
        initComponent();
    }

    void initComponent() {
        mComponent = DaggerRoboSampleComponent.builder()
                .applicationModule(getApplicationModule())
                .build();
    }
}

Conclusion

The fact that robolectric allows you to use a custom test application object (even a different one for different tests) together with dagger is an easy way to inject mock object without having to rely on ugly setters.

Robolectric is a fast and effective way to speed up your tdd process. All the time spent to set the tests and the mocks app is well repaid in code coverage and writing and debugging speed afterwards.

See it in action (and have something to copy from)

Here on github I put a working example that demonstrates how to inject a mocked module using robolectring.

It's Been a While

.. since my last blogpost.

I’ve done a few things in the meanwhile, I wrote a game with LibGdx, I tinkered with various frameworks, but on top of all these things I’ve been taking care of my one (and a half) year old daughter.

I do certainly have less time to devote to side projects, but I still like to learn new things and Android is exciting from that point of view.

While trying to catch up with all the new things that keep happening in the Android World, I hope I’ll be able to post more often here.

PS: I used this post to reacquatain myself with octopress

Dragging With ViewDragHelper

While working on my last side gig, a patch to Firefox for Android to allow the urlbar to be dragged in order to show content hidden behind the main view, I had to deal with ViewDragHelper and understand how it works.

The final result (please note that the patch is still under review) is something like this:

It caused me more than one headache, and for this reason I am writing this post hoping it might be helpful to anybody wanting to tinker with it.

ViewDragHelper’s usage is not well documented, but this post by Flavien Laurent is the best place you could start from.

In order to provide a simpler example for this post, I’ll introduce a simplified version of what I have done on Firefox, without all the extra code needed to interact with the rest of the app.

Let’s start with..

How touch events are handled

A good source of information is the official documentation. However, I’ll write a short introduction here.

Whenever a touch event happens, the parent view is being asked if it wants to handle that event in place of its children. This is done by calling its onInterceptTouchEvent() method, which should return true if the parent view wants to handle the event.

In case the event is trapped by the parent, its onTouchEvent() method gets called and it must return true if the event is handled.

Children view can also rebel against their parent tiranny, and disable this mechanism by calling requestDisallowInterceptTouchEvent(). By doing that, they ensure that the touch event wont be passed to the parent view.

images

How ViewDragHelper works

The idea behind it is pretty simple. You register a draghelper on a container view

1
mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallback());

and then you set a couple of entry points, one to listen if a drag is being started (or is in progress), the other to handle the motion events and perform the dragging when the event is being passed to the view it registered against:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (mDragHelper.shouldInterceptTouchEvent(event)) {
            return true;
    }
    return super.onInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    mDragHelper.processTouchEvent(event);
    return true;
}

ViewDragHelper will be asked to check if a motion event is part of a dragging process. The behaviour of the whole dragging process is ruled by a DragHelperCallback instance passed on creation. DragHelperCallback has method that need to be implemented to be notified of particular evens, such as:

  • a change in the dragging state
  • a change in the dragged view location
  • when and where the dragged view was released

It also has methods used to influence the dragging behaviour:

  • clamp the position of the view / the range it can be dragged within
  • check whether a particular subview can be dragged

A whole drag process is intended a sequence of Down / Move / Up events over a particular target view. Whenever a drag process starts, ViewDragHelper finds the topmost child that contains the location of the motion event, and asks us if that particular view can be dragged or not in tryToCaptureView() method.
This is more or less the theory involved in the dragging process. On top of that, ViewDragHelper offers also settleAt methods to let the views settle to their rest location gracefully.

Since explaining in words it’s not the easiest thing (nor I am particularly good to explain), I’ll introduce the simplified app I used to understand (a bit) how ViewDragHelper works.

Enters DragQueen

images Licensed under commons creative

(Just kidding). DragQueen is a (ultra) simplified version of what I implemented on fennec with a button named queen that you can drag.

It consists of:

  • OuterLayout (the root element of our activity, the one that contains the views we want to drag)
  • a front panel which can be dragged

images

To make the things a bit more complex we want to enable the dragging only from a particular subview, Queen. To make the things even more complex, we want to be also able to interact with Queen button while the dragging is not happening.

We also allow only two rest locations, so if the view is released mid-way it will settle to its open / close location depending on the speed and the location of when the view is released. Finally, note that OuterLayout contains also a button that is hidden when main layout is in its closed state.

OuterLayout

Outerlayout is a ViewGroup that extends a RelativeLayout.
As I wrote before, the two methods ViewDragHelper needs to hook into are

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (isQueenTarget(event) && mDragHelper.shouldInterceptTouchEvent(event)) {
            return true;
    } else {
        return false;
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (isQueenTarget(event) || isMoving()) {
        mDragHelper.processTouchEvent(event);
        return true;
    } else {
        return super.onTouchEvent(event);
    }
}

You may notice that onInterceptTouchEvent if has another condition. This is because we want to drag mainlayout only if the touch targets the Queen (it would not be drag-queen otherwise). This is a simplified version of what happens in Fennec, where we want to intercept the drag only if it starts from the toolbar to avoid to interfere with the web content.

In any case, checking if Queen is targeted is quite easy:

1
2
3
4
5
6
7
8
private boolean isQueenTarget(MotionEvent event) {
    int[] queenLocation = new int[2];
    mQueenButton.getLocationOnScreen(queenLocation);
    int upperLimit = queenLocation[1] + mQueenButton.getMeasuredHeight();
    int lowerLimit = queenLocation[1];
    int y = (int) event.getRawY();
    return (y > lowerLimit && y < upperLimit);
}

Other methods that influence the behaviour of the dragging are:

tryCaptureView

1
2
3
4
@Override
    public boolean tryCaptureView(View view, int i) {
        return (view.getId() == R.id.main_layout);
    }

which gives draghelper the permission to drag main layout). You must return true up there for the view you want to be dragged.

getViewVerticalDragRange && clampViewPositionVertical (there are Horizontal flavours too)

1
2
3
4
5
6
7
8
9
10
    public int getViewVerticalDragRange(View child) {
        return mVerticalRange;
    }

    @Override
    public int clampViewPositionVertical(View child, int top, int dy) {
        final int topBound = getPaddingTop();
        final int bottomBound = mVerticalRange;
        return Math.min(Math.max(top, topBound), bottomBound);
    }

which do what you expect them to do, setting limit for the dragging. In this particular case, vertical range is set to half the size of screen.

DragQueen

Note also how mMainLayout is set as clickable with android:clickable="true". This prevents touch events to be passed down to the view below when it is closed..


Callbacks

There are several callbacks you will want to implement in order to react to the events related to the dragging:

onViewDragStateChanged

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
    public void onViewDragStateChanged(int state) {
        if (state == mDraggingState) { // no change
            return;
        }
        if ((mDraggingState == ViewDragHelper.STATE_DRAGGING || mDraggingState == ViewDragHelper.STATE_SETTLING) &&
             state == ViewDragHelper.STATE_IDLE) {
            // the view stopped from moving.

            if (mDraggingBorder == 0) {
                onStopDraggingToClosed();
            } else if (mDraggingBorder == mVerticalRange) {
                mIsOpen = true;
            }
        }
        if (state == ViewDragHelper.STATE_DRAGGING) {
            onStartDragging();
        }
        mDraggingState = state;
    }

notifies the state transitions of DragHelper between DRAGGING, IDLE or SETTLING state.

onViewPositionChanged

1
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {

whose purpouse is pretty clear.

onViewReleased

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    @Override
    public void onViewReleased(View releasedChild, float xvel, float yvel) {
        final float rangeToCheck = mVerticalRange;
        if (mDraggingBorder == 0) {
            mIsOpen = false;
            return;
        }
        if (mDraggingBorder == rangeToCheck) {
            mIsOpen = true;
            return;
        }
        boolean settleToOpen = false;
        if (yvel > AUTO_OPEN_SPEED_LIMIT) { // speed has priority over position
            settleToOpen = true;
        } else if (yvel < -AUTO_OPEN_SPEED_LIMIT) {
            settleToOpen = false;
        } else if (mDraggingBorder > rangeToCheck / 2) {
            settleToOpen = true;
        } else if (mDraggingBorder < rangeToCheck / 2) {
            settleToOpen = false;
        }

        final int settleDestY = settleToOpen ? mVerticalRange : 0;

        if(mDragHelper.settleCapturedViewAt(0, settleDestY)) {
            ViewCompat.postInvalidateOnAnimation(OuterLayout.this);
        }
    }

is where you (might) want to let the view go into its rest place. I made it behave in such way that dragging speed (and direction) is more important than the place you are releasing the view.


Bonus methods

1
mDragHelper.settleCapturedViewAt(0, settleDestY))

is a helper method that will make your view smoothly settle at the given destination.


Quirks and reasons for headaches

ViewDragHelper sets the offset of the target view ..

.. by calling offsetTopAndBottom, which is ok but you have to remember that a layout round called by any of the children of outerLayout (or the parent view you are passing to the draghelper) will reset that offset. What you are going to see in that case is your dragged view getting back at its rest position.

A possibile solution to this is to force back the parent where it was before:

1
2
3
4
5
6
7
8
9
10
11
mMainLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            if (mOuterLayout.isMoving()) {
                v.setTop(oldTop);
                v.setBottom(oldBottom);
                v.setLeft(oldLeft);
                v.setRight(oldRight);
            }
        }
    });

ViewDragHelper always want to intercept the top most child in z order

If you have some view in between, but you want to be able to drag a lower one, you have to let ViewDragHelper think that your view is the topmost one.

1
2
3
4
5
6
7
8
9
    @Override
    public int getOrderedChildIndex(int index) {
        int mainLayoutIndex = indexOfChild(mMainLayout);
        if (index > mainLayoutIndex) {
            return mainLayoutIndex;
        } else {
            return index;
        }
    }

What’s more

ViewDragHelper offers a lot more features than those I just presented. DragQueen implements only vertical dragging, but you can drag your views horizontally too. Again, refer to the excellent post by Flavien for more details.

Moreover, ViewDragHelper allows you to intercept drag events that start from the edge of the screen, which is the way its used in the NavigationDrawer.

All it needs to enable it is to call

1
mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);

and to implement

1
2
3
4
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
  mDragHelper.captureChildView(mMainLayout, pointerId);
}

TL;DR

ViewDragHelper is a bit complex and as I said before not well documented. However it allows you to drag views around with very little code, and it can be used to implement nice effects. In any case you can unrestrainedly copy take inspiration from DragQueen source code on GitHub (it seems to work). I really hope this post does not contain too many errors and that you enjoyed reading it as much as I did writing.

If you liked this post, consider following me on twitter @fedepaol

Migrating From Blogger to Octopress (Done!)

It feels a bit like this Light bulb

but when I had to write a new blogpost and had to embed some code snippets into my blogger hosted blog, I got so pissed of that I chose to migrate my existing blog to a github hosted instance of octopress.

Jason Jarrett made a pretty nice tutorial about the whole process here. However, I had to change a couple of things and I thought those might be helpful to anybody who faces the same problems.

The overall process is something like:

  • setup octopress
  • import an exported dump of blogger
  • fix internal links
  • setup redirects from blogger to your new blog

Setting octopress up

Nothing to say here. Just go to octopress website and follow the instructions.

Importing posts from blogger

This is pretty straightforward too. Export your blogger content as xml, and use this ruby script that generates a posts folder containing all the posts exported from blogger. Anyway, refer to Jason’s blog, everything is described accurately there.

Fix internal links

You’ll have to play a bit with sed in order to fix internal links, otherwise they will keep pointing to blogspot.

Setup redirects

Here is where things get interesting, because you will want to make visitors of the old url be redirected to the new blog (possibily with 301). The whole process is a bit tricky due to blogger limitation (for more details check here).

There are a couple of other obstacles too: the script available is powershell only. Moreover, Jason suggets to use the alias plugin which seems to be broken at the moment.

However, jekyll-redirect seems to work fine, so I chose to use it in my solution.

And finally, since powershell is not an option, here is my python version of the script. It binds the post id with the title of the posts, loop all the html files in your post folder, injects the redirection in the yaml header.

Using it is as easy as calling:

1
python blogger_import.py -p octopress/source/_posts/ -b ./blog-08-22-2014.xml

where p is the path of your posts folder, b is the xml file produced by blogspot.

Here is the script:

TL;DR

  • Read Jason’s blog
  • When setting up redirection, install jekyll-redirect
  • Use my script to inject redirection in the header of exported blogposts
  • Setup blogger template as described in Jason’s blog

PS: I still need to write the blogpost that made me switch to octopress.

Generating Preloaded Sqlite Data

Preloading data in Sqlite is a common problem during android development.
The most common solutions are:
  • hardcode the insert statements and execute them (possibly inside a transaction) the first time the db is opened
  • place the data inside a csv file, load it the first time the db gets opened, parse the rows and populate the db
  • prepare a pre-built sqlite file, ship it along with your app and load it the first time the db is opened


    I’ll focus on the third approach, because it allows us to check our db outside the app without extracting it from our device, and because it allows us to prepare the data in a more “human friendly way”.

    It’s worth to mention the excellent sqlite asset helper library by Jeff Gifelt, that allows us to embed a prebuilt (compressed) sqlite file without having to reinvent the wheel. For this reason, this post will be about how to handle data entry process (and something more), and you won’t find a (yet another) way to preload a sqlite file.

    Let’s start with a problem: you want to build a pretty simple Seasonal Fruit and Vegetables app, and the amount of data you have to deal with is big enough to discourage you to prepare the inserts manually.
    You’ll have:
    • the list of products
    • the description of each product (possibly localized in different languages)
    • the data related to the seasonality of each product
    So, here’s the approach:

    Step 1: data entry

    Use a spreadsheet to fill the data in a human friendly way, export it as csv (or tsv, so you won’t have to deal with any random comma inside the descriptions), parse it and produce the sqlite file together with localized string res files to be embedded inside the application.
    In my case I had a file  having the genre (fruit or veg), the calories count, the name and the description in italian and in english:

     asparagus     0     25     Asparagi     Descrizione asparagi in italiano.      Asparagus     English asparagus description  
    chard 0 12 Bietola Descrizione bietola in italiano. Chard English chard description


    I also have files that describe the seasonality of each products in different areas, but I will not describe them since they are not relevant to the approach I am describing here.

    Step 2: Parse!

    Choose your favorite scripting language. I went for python since it’s super slick and it comes with batteries included, such as xml writing and sqllite support.

    Creating the db is straightforward:
     CREATE_ITEMS = 'create table Item (_id integer primary key, Name text, kind integer, calories integer);'  
    CREATE_ITEM_PER_MONTHS = 'create table ItemPerMonth (ItemId integer, Month integer, Freshness integer, Area integer);'
    CREATE_ITEM_PREFERRED = 'create table PreferredItem (PreferredItemId integer);'
    conn = sqlite3.connect('fruit')
    c = conn.cursor()
    c.execute(CREATE_ITEM_PER_MONTHS)
    c.execute(CREATE_ITEM_PREFERRED)


    Then we need to use the data we have to fullfill two purpouses:
    • fill the database
    • fill the localized string resources 
    Again, filling the database consists of parsing each line of the csv file and calling the appropriate insert.

    In python is as easy as calling

       cursor.execute(statement)  

    on a cursor object, where statement is the insert statement.

    Together with that, we do have a lot of data that needs to be rendered in the proper language.
    In order to take advantage of the resource framework, I chose to generate the resource files instead of relying on a “locale” field in the db to filter in my queries.
    Again, filling an xml node is pretty straightforward in python:

       name = ET.SubElement(root, "string")  
    name.set("name", item_name)
    if lang_name.find('%') != -1:
    name.set("formatted", "false")
    name.text = lang_name


    At this point, we can generate an it_descriptions.xml file and an eng_descriptions.xml file (and even let our script place them in the proper folders).

    When we want to use our descriptions in Android (i.e. in  our cursor adapter’s bindView), we  need to bind the product name (i.e. “asparagus”) with the corresponding resource. That’s easy and it can be done in this way:

      int nameResID = context.getResources().getIdentifier(name,   
    "string", context.getPackageName());

    By doing that, we can retrieve the resource id of the string related to the name that was generated by our script. If we are worried about the cost of the lookup, we can even add a lru cache to absorb that cost.


    TL;DR:
    • Write your data in a human readable format
    • Parse that data with your favourite language
    • Write the data that does not depends on the language in sqllite
    • Write the language-dependent data in resource files
    • Use getIdentifier for retrieving the resource id of the strings automatically generated
    Bonus point: again, you can use this convention for pictures as well, so you can throw an “asparagus.png” image in your assets to be loaded afterwards.

    The biggest advantage of this approach is that you have only one master source of your data (the spreadsheet) that you can modify and rerun the generator over every time you modify it.

    If you are interested in the whole loader python script you can check it here