Monday, May 30, 2016

Android MVP Architecture

On the never-ending journey to go from hobby programmer to professional, I am always on the lookout for good programming practices. A couple of weeks ago, I found a sample Android TODO app from Google. This app was created to demonstrate how one might organize and architect an Android application. In this post, I'll discuss what I learned from this project.

Android environment

I haven't done any Android programming in a while, so I had to spend some time getting my Android Studio, the SDK and other things up to date. After a few rounds of downloads, updating and restarting, I was ready to work.

I read that that the new version of Android Studio had some big improvements in emulator performance, but I didn't really notice much difference - things are still bad. On both the emulator and on a real phone, I ran the app without any issue. But the emulator performed terribly with the instrumentation tests. First, some of the tests failed only on my emulator. Second, the emulator took about 20 minutes to run all tests, whereas the phone took about 2 minutes.

It looks like I can do some developing with the emulator, but given my set up, it's still not really a viable solution. For now, I'll just move on.

File organization

When you build projects with Android Studio, it creates some folders and files for you. The top level of the todo app looks like this:

app/
build/
build.gradle
gradle/
gradle.properties
gradlew
gradle.bat
local.properties
settings.gradle
todoapp.imp

and that is pretty similar to all Android apps that I've created in Android Studio.

The major difference I see in this sample apps and ones that I have worked on is that there are a lot more src folders:

app/src/androidTest
app/src/androidTestMock
app/src/main
app/src/mock
app/src/prod
app/src/test

The main/ folder holds most of the code that is used in the app. It will be used in all build variants and flavors.

There are two product flavors listed in app/build.gradle, mock and prod, which correspond to two of the src folders. They both have files that define a class called Injection. This is a little interesting and new for me. The prod and mock versions of this class do the same thing except the mock uses a faked class, which is also defined in the mock directory hierarchy. So, depending on whether we are building a mock or prod version of the app, we will use real or faked classes.

This leaves three test folders androidTest, androidTestMock, and test. Based on the comments (I think): test defines unit tests; androidTest defines integration tests; and androidTestMock defined integration tests that use mock classes. I found this naming to be a little confusing at first, but I think I get it now -- since android is the instrument we're using, androidTest == instrumentTest.

Now that I have a handle on the file organization, I'll look at some code.

Model view presenters

This todo app is implemented using a Model-View-Presenter (MVP) architecture.

In android, things start in an Activity class, and it creates each part of the MVP app. For example:

  • TasksActivity is an AppCompatActivity
  • TasksActivity creates a TasksFragment which is the View
  • TasksActivity creates a TasksPresenter which is the Presenter
  • TasksActivity creates a TasksRepository which gives access to Task objects which is the Model

The Presenter is constructed with references to the Model and the View.

mTasksPresenter = new TasksPresenter(
  Injection.provideTasksRepository(getApplicationContext()),
  tasksFragment);

and the view is aware of the presenter, like so:

public TasksPresenter(  
    @NonNull TasksRepository tasksRepository,   
    @NonNull TasksContract.View tasksView) {  
  ...
  mTasksView.setPresenter(this);
}

This pattern is done for each of the different Activity's. Data from models are processed by the Presenter to be rendered by the View. Conversely, updates from a user can be sent through the View to the Presenter onto the Model.

Conclusion

This sample app is nicely organized and it's something I can emulate in my projects.

Sunday, May 15, 2016

End of Algorithms 2

After falling a bit behind schedule, I am almost finished with Algorithms II from Coursera. I have finished all of the prgramming assignments and all of the lectures. All that remain is the final round of exercises.

Like many worthwhile pursuits, I am glad that I went through the classes (both Algorithms I and II), and also happy that it is over.

There were a lot of things I think I gained from the experience. It gave me a good survey of lots of data structures and algorithms. I wanted to fill-in holes in my knowledge of algorithms, and I think that these courses have done just that. For all of the more advanced subjects, I need to take deeper dives, but I am happy that I have a good breadth of knowledge at least.

Additionally, since Algorithms is taught with Java examples, I got to work with a foreign language and its specific coding style and tool-set. While frustrating at times, it's fun to try new things.

And opposite the 'new', the lecturer shared many interesting historical anecdotes throughout the course. I'm not really big on history, but I think these little tidbits made the material a bit more colorful, which also makes it easier to recall things.

A bit of advice

Now that I am about to finish my second massive online course, I wanted to offer you (and future me) some advice about taking online courses:

  • If you start it, finish it. If you say to yourself, "I'll see how it goes", you will undoubtably quit.
  • Do everything. Watch the lectures, do the exercises, do the projects, participate in forums.
  • Set a time(s) in your day/week to do the work. Schedule it like an appointment that you can't miss.
  • Keep up with the new material and the deadlines (even if they're not really enforced).

What I am saying is, be hard on yourself. Don't let yourself have an excuse for not finishing the course. It's so easy to start and quit.

What's next?

I don't have any plans to take any other Coursera courses in the immediate future. I'll check in again later, but I don't see anything that I'd really want to invest time into for now. So, I don't expect to commit anything else this year.

Luckily, I have a nice backlog of study items that I want to work on. More on that later ...