Freitag, 21. August 2009

Scala Actors in Android


I experimented with scala Actors in android today.

It all works very nice, except that the actors classes are not in the scala-android library, but including the scala-library.jar and having proguard take care of removing unnecessary classes worked very well...

The actors work, only problem is that updates to Views should only be made from the main UI thread, so i added a function to allow to append Messages to TextViews by post()ing them...

Adding an click listener to a button:

// converter for anonymous func to OnClickListener
implicit def func2OnClickListener(func: (View)=>Unit):OnClickListener = {
new OnClickListener() {
def onClick(v:View) = func.apply(v)
}
}

button.setOnClickListener(
(v:View)=>{
textView.append("click from thread: " + Thread.currentThread().getId() + "\n");
buttonActor!"msg";
scrollViewUpdate(scrollView)
})


The ClickListener is outputting some code to the textView, and then sends "msg" to a actor... the Actor class and the messages used to post() functionality to the Views looks like this:

/* since views should only be accessed by the UI Thread, i use this method from ButtonActor to post the message to the TextView */
def textViewAppend(textView:TextView, msg:String) {
textView.post(()=>{
textView.append(msg)
() // must return Unit
})
}

def scrollViewUpdate(scrollView:ScrollView) {
/* post function for scrollView, after updates, we want to scroll to bottom... */
scrollView.post(()=>{
scrollView.fullScroll(View.FOCUS_DOWN)
() // must return Unit
})
}

class ButtonActor extends Actor {
private val textView:TextView = findViewById(R.id.TextView01)
private val scrollView:ScrollView = findViewById(R.id.ScrollView01)
private val spinner:Spinner = findViewById(R.id.Spinner01)
def act() {
loop {
receive {
case msg =>
val textMsg = "msg received: " + msg.toString() + " from thread: " + Thread.currentThread().getId() + "\n";
textViewAppend(textView, textMsg);scrollViewUpdate(scrollView);
}
}
}
}


See it all here:

http://github.com/phueper/AndroidScalaAntTest/

Cheers, Patty

Donnerstag, 20. August 2009

Generics in implicit conversion functions

Playing with scala i started using implicit conversion classes... e.g. to use
findViewById
in the Android SDK:

val textView:TextView = findViewById(R.id.TextView01)

now findViewById returns a android.view.View (the base class of all views). In Java we would cast to a TextView, which can be done expicitly in scala using asInstanceOf[]. However, using implicit conversion functions is somewhat easier to read once understood...
So this is my first version of the conversion function:

implicit def textViewConverter(v:View):TextView =
{ v.asInstanceOf[TextView] }

If scala now finds a View being assigned to a TextView variable, it will try to find a conversion funtion, that converts from View to TextView and apply it "automagically".
Now this would mean writing one conversion function for every View type i am using... after having written the third conversion function i thought that there must be a better way... and there is! Using generics i can write the following conversion function:

implicit def viewConverter[T](v:View):T = {v.asInstanceOf[T] }

This will convert from View to any other type!

Now it would be neat if i could restrict T to be only of types inside android.widget... but i am not sure wether that can be done...

Cheers, Patty

Sonntag, 9. August 2009

First Steps with Android and Scala

I am trying to learn scala and i would like to write some apps for my Android phone...

So i thought i will combine the two.. i started to learn about writing an android app using scala...

I read some blogs on the web and pulling together ideas from different source (android.com / proguard.sf.net, http://chneukirchen.org/blog/archive/2009/04/programming-for-android-with-scala.html) i created my first Hello World Android App written in scala:

I published the git tree here:

http://github.com/phueper/AndroidScalaAntTest

It contains all steps from creating the Eclipse project, transferring it to an ant based project, adding scala and proguard to creating Hello World in scala...

Next steps:

- run the app on my G1, instead of the Android Emulator
- learn more about debugging...
- a real/useful Android application... i have some ideas of apps that i would like to use...

Cheers, Patty