Showing posts with label application development. Show all posts
Showing posts with label application development. Show all posts

Saturday, December 8, 2012

Scala And Android Were Made For Each Other

I've been experimenting with Scala for a while now, and the more I use it, the more I like it.  Scala isn't exactly what I would call an approachable language, but if you are familiar with Java or C# and you slowly work your way into it, Scala is really a joy to work in.

I also like to write apps for Android.  Since Scala runs on the JVM, it runs on Android, too.  Recently I've started to think that Google made a mistake using Java for Android.  It probably helped Android gain apps and popularity since thousands of developers could install the Eclipse Android Plugin and start coding, but that's the thing - Coding on Android is very different than coding, say, a Web app.  It's even quite different than coding a desktop app.  And it is because of the way that things should be written on Android that Java seems to be a poor fit.  All those thousands of programmers started writing apps - and did it wrong.

I know.  I made tons of mistakes.  As I read more about the platform and become more familiar with how things ran, it is clear that a lot of what I did often wasn't a best practice.  Some of what I did was just wrong.

This is where I get to the title of this post.  I recently experimented and wrote an application for Android using Scala.  I have to say, after writing the application this way, I don't ever want to go back. It is my sincere belief that Scala is a much better fit for writing applications on Android than Java.  To prove my point, I am going to go through the app I wrote and show you the Scala code. I am going to assume if you are reading this that you already have some familiarity with Android development so I will refrain from showing the Java alternative.

I'm also going to point out that I am in no way a functional programming expert.  As I said, I use Scala as a better Java.  My code continues to become 'more functional', but I'm sure this is not idiomatic Scala.  That's okay by be, though, because things are just easier.  To me, that's the best measure of how good the code is.

Background

We recently had half our staff move to an office in San Francisco.  Our company has always moved at a rapid pace, but with the additional overhead of working with a team 2 hours difference and across the US, I was feeling like I was getting distracted. I wanted to find a management technique that was simple and that would help me stay on track.  I picked the Pomodoro technique - it was simple. It suited me. It was invented by a programmer, and there were several apps in the Play store for me to use. Of course, I wanted to write my own anyway.

For the purpose of this app, all you need to know is that a Pomodoro is a 25 minute block of time where you concentrate on doing work. Since this is a pretty straight forward app to write, though, I thought I would implement it in Scala to see how it went.

If you want to know more about the Pomodoro Technique, you can visit the official Pomodoro Technique page or Buy the book on Amazon (convenient link on the left).




Application Definition

Here are the things I want the application to do:
  • Allow me to start a Pomodoro (a 25 minute block of time)
  • Play the ticker sound while in a Pomodoro (for some reason, hearing this helps me stay on track)
  • Play a bell when the Pomodoro finishes
  • Allow me to cancel a Pomodoro if I have to
  • Keep the Pomodoro timer running, even if I close the application 
Here are the constituent parts of my application:
  • Activity - Main activity, only Activity.  It has the text that shows you the time left and a button that changes states.  The button will either start or stop the timer.
  • Service - A background service that will run the timer task - counting down 
If you've done any Android programming in the past, you realize that even these simple requirements will result in a slew of callbacks, threads, anonymous inner classes, binders, messengers...need I go on?  Okay, that was a bit of an exaggeration, but not as exaggerated as it seems.

Let's think about this for a moment. In order to prevent ANR warnings we need to keep things off the main thread, which, means any communication with our service should be run in separate threads.  Allowing the service to run separately from the Activity (and allow it to potentially be started and called from any activity, even someone else's) will require it to be started and bound so we'll need a Binder and then we'll need to implement its callbacks. Then communication should happen with Messages so we'll need a Messenger and we'll need to implement its callbacks. Oh, and if we want to update the UI so users know whats going on, we need to then run updates from background threads on the UI thread, which, requires a Runnable.

When you add all this up, it makes for lots of  boilerplate code.  Thankfully, the language features of Scala make this less verbose, easier to write,  more understandable, and ultimately easier to maintain.  It also makes it much easier to write code that will follow Android best practices.

Now that we know the what and the how, let's talk code.

The Code


We know we want a bound service that we can send messages to.  When you read the Android docs on it, you'll see that there is a abstract inner class that implements Handler and is passed to a Messenger that is returned in the Services onBind method.

Wow, that was a lot to say.  It is also a lot of boilerplate code.  I wanted to move this to a common class so it was out of my way.  In Java we might make an Abstract base class.  But wait, the Activity in our application also needs a Handler and a Messenger, and if we Make an AbstractService, we could not use that code in an Activity. If we make an AbstractActivity, we cannot use it for our Service.   Here is the first place where Scala is quite handy.  I was able to make a Trait.  Traits are very powerful and I'm using the one below as a 'better interface', which, might be under-utilizing this great feature.  It serves its purpose well, however.

1:  trait MessageReceiver {  
2:   implicit def toIncomingHandler(f: Message => Unit): Handler = new Handler() { override def handleMessage(message: Message) = f(message) }  
3:    
4:   val mMessenger = new Messenger({ m: Message => 
5:    onMessage(m)  
6:   })  
7:    
8:   def onMessage(m: Message)  
9:  }  

Notice that I also used an implicit to reduce the need to declare an abstract inner class to handle the message.  I probably didn't save any code, but I like the way this looks far better than the Java alternative.

Now that we have the MessageReceiver defined, let's define our Service.  Before I show you the code, here are some things I want you to notice about the class:

  • We override onMessage and implement it.  This is the only code in this class that is related to receiving a message.  All the boilerplate has been moved to the Trait which can be used by both Activity and Service classes.
  • The start method has an internal method called timer that is recursive. This also happens to be tail recursive, and Scala is smart enough to unwind this, so it won't grow my stack.  
  • We run the timer in a background thread.  Notice that all we have to do is surround it with a spawn{} block.  (I omitted the imports, but you need to import scala.concurrent.ops._ to do this)


1:  case class BackgroundTimer extends Service with MessageReceiver {  
2:     
3:   var millis = 0L;  
4:   /** Keeps track of all current registered clients. */  
5:   var mClients = List[Messenger]()  
6:   var currentTime = "0:00"  
7:    
8:   val mediaPlayer = new SoundPool(2, AudioManager.STREAM_MUSIC, 0)  
9:    
10:   var tickId: Int = -1  
11:   var alarmId: Int = -1  
12:   var tickStreamId = -1  
13:     
14:   override def onMessage(m:Message) = {  
15:    m.what match {  
16:     case BackgroundTimer.REGISTER =>
18:       mClients ::= m.replyTo  
19:      }  
20:     case BackgroundTimer.UNREGISTER =>
21:      if (m.replyTo != null) {  
22:       mClients = mClients.remove(messenger =>
23:        if (messenger == m.replyTo) {  
24:         true  
25:        } else {  
26:         false  
27:        })  
28:      }  
29:     case BackgroundTimer.START >  
30:      start()  
31:     case BackgroundTimer.STOP =>
32:      //don't play the alarm bell  
33:      stop(true)  
34:    }  
35:   }  
36:    
37:   override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = {  
38:    Log.i("BAA", "Received start id " + startId + ": " + intent)  
39:    try {  
40:     tickId = mediaPlayer.load(this, R.raw.singletick, 1)  
41:     alarmId = mediaPlayer.load(this, R.raw.alarm, 1)  
42:    } catch {  
43:     case e: Exception => Log.d("BAA", e.getMessage())  
44:    }  
45:    Service.START_STICKY; // run until explicitly stopped.  
46:   }  
47:    
48:   /**  
49:    * Must override this to allow the service to bind to the Activity so we can start/stop timers  
50:    */  
51:   override def onBind(intent: Intent): IBinder = {  
52:    Log.i("BAA", "OnBind called")  
53:    return mMessenger.getBinder()  
54:   }  
55:    
56:   def start() = {  
57:    if (millis == 0) {  
58:     spawn {  
59:        
60:      var alarmStreamId = -1  
61:      try {  
62:       tickStreamId = mediaPlayer.play(tickId, 2.0f, 2.0f, 1, -1, 1.0f)  
63:      } catch {  
64:       case e: Exception => Log.d("BAA", e.getMessage())  
65:      }  
66:        
67:      def timer(millisLeft: Long): Unit = {  
68:       if (millis > 0) {  
69:        millis = millisLeft  
70:       }  
71:       val seconds = (millisLeft / 1000) % 60;  
72:       val minutes = ((millisLeft / (1000 * 60)) % 60);  
73:       currentTime = minutes + ":" + (if (seconds > 9) seconds else "0" + seconds)  
74:    
75:       if (millis > 0) {  
76:        mClients.foreach { messenger =>
77:         val response = Message.obtain(null, BackgroundTimer.TICK, 0, 0, currentTime)  
78:         messenger.send(response)  
79:        }  
80:        Thread.sleep(995);  
81:        timer(millisLeft - 995)  
82:       } else {  
83:        stop(false)  
84:          
85:       }  
86:      }  
87:      //now start it off...  
88:      millis = 1000 * 60 * 25  
89:      timer(millis)  
90:     }  
91:    }  
92:   }  
93:    
94:   def stop(forced:Boolean) = {  
95:    millis = 0  
96:    currentTime = "0:00"  
97:    mediaPlayer.stop(tickStreamId)  
98:    if(!forced)  
99:     mediaPlayer.play(alarmId, 0.2f, 0.2f, 1, 0, 1.0f)  
100:    mClients.foreach { messenger =>  
101:     val response = Message.obtain(null, BackgroundTimer.STOPPED, 0, 0, currentTime)  
102:     messenger.send(response)  
103:    }  
104:   }  
105:  }  
106:    
107:  /**  
108:   * Define an object to hold some statics  
109:   */  
110:  object BackgroundTimer {  
111:   val REGISTER = 1  
112:   val START = 2  
113:   val STOP = 3  
114:   val UNREGISTER = 4  
115:   val STARTED = 5  
116:   val STOPPED = 6  
117:   val TICK = 7  
118:  }   
119:    

I don't know about you, but this class looks very clean to me.  Almost all the code is directly related to what this class is intended to do with no messy boilerplate code for messaging or threading.  In fact, threading is now too easy -  just add a spawn block and done.  The 'business logic' is also very compact.  Since timer can be declared inside start, all the logic for actually running the timer is in one spot - no need to jump to a different section of code to see what's going on.

Want to try the app out?  Download Campari Pomodoro.

Next up, the Activity

Thursday, May 6, 2010

Android Application Part 3 - UML

This post is part 3 of a series.  Click here to go to part 2.

Before I go into the actual UML for this application, I first have to talk about my opinion regarding things like UML Diagrams, Sequence Diagrams, State Diagrams, Activity Diagrams and Object Diagrams.  As Software Engineers, we differ from other Engineers in a major way.  The only thing we produce that is a COMPLETE representation of the systems we build is the code.  In no other engineering endeavor is the completed product also the description of that product.

Based on this knowledge, it is my belief that all the diagrams and drawings and 'design' aides we use to build software are there not to completely document a system.  On the contrary, attempts to completely document a system using these tools is rather counter-productive.  So what are they supposed to be used for?  I like to think of all these diagrams and pictures as tools to be used for the following purposes:

  • To allow the Software Engineer to organize his thoughts about the system, and aide in his decisions regarding the design.
  • To provide a way to describe a PART of a system that may be important or complicated at a high leve
  • To allow the view of a system at a higher, abstract level, without the details, to allow for a broad analysis of a system
That's it.  That's all.  That's what all these things are good for.  I know the very next question people will ask - What if we really need to understand the details?  What if we need to KNOW what the system is doing?  Well, there is only one reliable way for someone to know what a software system is doing - GO READ THE CODE!

So, when I produce UML, State or Sequence diagrams, I typically omit a lot of detail.  I intend for these things to convey limited messages and present limited data because they are simply tools of transition, there to help in the final build of the system.  Now I will get off my soapbox and present to you the simple designs for my app.

The UML

As you can see from the UML, this is a pretty simple object model.  We'll see if I need something more complex later, but this appears to be the basic outline for what I need. 

Notice that I added some auditable information to the Items.  I figured you would want to know who and when an item was added, removed, updated, etc.   




To the right, you will see my DAO UML diagram.  As you can see, I have declared a Dao interface that uses generics.  Each subclass will implement the generic type for its Type of object. I also chose to use a DaoFactory to create my objects.  You'll notice that I have not represented all the relationships, return types, arguments, etc, that would make this UML complete.  Isn't this version much less cluttered, though?  And isn't my intent straight forward?



I intend to use GWT for my Web site, so I have a set of RPC services that will extend RemoteServiceServlet.  As you can see, there is nothing magical here.  It is implied that each of these services will use the corresponding DAO associated with them.  I could add those relations to this UML, but I think it just adds complexity.


I am going to refrain from building the UML for the visual components of this system.  Why?  For one, the diagrams get pretty complicated pretty fast.  And two, because I already have plenty of diagrams showing the 'guts' of my system. 

The Sequence Diagram

I will demonstrate one sequence diagram that is representative of this design.  Most actions in this system will follow this pattern:



The first thing I want to point out about the sequence diagram, is that it is rather hard to model the AsyncCallback used by GWT RPC.  I supposed I can add a call to the AsyncCallback constructor from UserServiceAsyc, and fit the model that way, but this is another scenario where that tends to obscure the intent rather than enlighten it.  Instead, I just put a comment that the GWT magic is omitted.  I hope that other developers looking at this would be familiar with GWT.

By the way, my favorite modelling tool is called, Violet.  It is completely free.  It's simple, but makes for a rather quick and easy way to build your models so that you can get your thoughts together and start coding.

Next: We'll get into some coding. FINALLY!

Tuesday, May 4, 2010

Android Application Attempt 2

Now that my classes have finished, I am going to attempt an Android application again.  My first idea was a 'my friends' application.  It appears that Google has beat me to it.  Thanks, Latitude.

I have a second idea.  This application I call, 'Family Shopping List'.  The idea is to store a common list, say a grocery list, online, and sync it to all the family accounts tied to the list.  This way, my wife can add milk to the list, and I can pick it up on the way home.  The reason this can't be strictly an online application is simple - Cellular service is often non-existent in grocery stores.  What we can do is sync the lists while we do have service, and show the list we have when we are offline.  So, here is a basic description of the very high-level design of 'Family List'.

  • Server application - A Web site with the ability to set up a new account, view lists, send invites to users.  Accesses a backend database where all information is stored
  • Web Service - Published interface that allows clients to interact with the server.  
  • Client - Android application that communicates to the server.  This application will also have a local data store that mimics some of the tables on the server
That's it in a nutshell.  For my next post I will be going over the basic design of the application.