 I'm Daniel Jackaway and this summer, thanks to Ruby's number of code, I worked on Rubato, which is working on bringing Android apps, or Ruby to writing Android apps, so you can bring Ruby to Android so you can write apps in Ruby. And so today I'm gonna talk about that and some related projects. So first of all, why are we, like some notes about mobile, first of all, it's surprisingly new, even though basically everyone including your mom has an iPhone, the app store's only two and a half years old, so really there's still a lot going on, there's a lot of new stuff, like we really have only scratched the surface in augmented reality, for example, there's a lot of new stuff to do with mobile and now tablets are coming around to add even more possibilities. Also, for some people it's very lucrative, it's hit or miss, but there are some big wins, any venture is gonna be hit or miss, but at least people are finally willing to pay for your software again, unlike online, where consumers usually aren't willing to pay. But you do have to use either Objective-C or Java right now in general, and that's not the best option, in the opinion of most people at Ruby Conferences. So if you say like, hey Apple, you know, you guys just want a Mac or Ruby, right, like we maybe, we ask nicely, no. Never Ruby on an iPhone, at least from time being, that's just not gonna happen. But Android can run anything that the JVM can run, so that includes Clojure, Scala, Jython, and even JRuby. Now JRuby does give you portability to run anywhere that JVM can, which includes App Engine and Android. But it's also just a really cool thing in general. It's pretty fast, roughly in line with 1.9. It has native threading, so you can saturate all the cores with one process. You can call Java, you can talk to Java libraries. There's all kinds of cool things about JRuby. LinkedIn is using it. You should definitely think about it. So now I'm just gonna give you kind of a whirlwind overview of the Android API, so we can kind of assume you guys don't really know much about the API as much as you know about Ruby. So first of all, the two main visual elements are activities and views. And activity is generally gonna be one screen full of things. So it's kind of analogous to a web page on when you're doing web development. So you'll have one activity that has a bunch of view elements within it, which are the views. And then when you shift to a new view, that's like a new screen, that's a new activity. I'm gonna illustrate that with a demo. So this is pretty much the first Rubalto script that I wrote. It's a very simple craps, the gambling game script. So this whole thing is one activity, and then each of these text boxes and buttons is a view. And then if I click this, this takes me to a new activity, and this is a view, or what's called a list view. And if I click this, this is yet another activity. These are both views, and I'll close it back. One cool thing about Android's UI is that basically you can always use the back button to get to the last activity you were on. So whereas in the iPhone, when you have a Twitter client or something and it wants to open links, it has a special API called open and embedded browser so that you can then just quit it and get back to the app. With Android, you can just hit the back button. It sends you to a normal browser and then they hit the back button. It takes you right back to the last activity, which is a different app, which is the Twitter app or whatever. So that's just one note. So then I go back here, I'll click this. This is a view, and I lost my back, but that's just it. So that's a quick idea. Each screen pulls that activity and each thing within it is a view. Then things that are a little hard to get illustrated visually. There are broadcast receivers, which basically pretty much any event, you can say I want a broadcast receiver to get it executed when this occurs. So that's everything from there's a time tick event, which basically just fires every single minute and that way you can do some kind of cron-like thing if you want it or stuff like that. And then it goes all the way to more interesting stuff like there's an SMS received event and you have to ask for the permission for that, but that means that any time they receive an SMS, you can be notified of that and then take advantage of that. And then there's also services, which run in the background. So the way Android's multitasking works is basically when you're on the activity, it's running and you can see to you and all that. But then when someone moves on to another activity, either within the app or to another activity in a different app, then that'll get paused. And it won't get killed, but it might get killed later if it needs the RAM back. So anything that you need to kind of keep going, even when the app isn't running, you do a service. So for example, I have a tethering app that lets me share my phone's internet with my computer. And there you open up an activity to tell it to start tethering. But then it does the actual tethering in a service and that way if the activity gets killed, I still have internet on my computer. And then finally, there's a lot of XML configs where you do things like define the name of your app. You can do layout in there. That's where you ask for permissions for more sensitive stuff, like asking and getting their location or reading their SMSes and all that stuff. So that's a quick overview. There's also, it's kind of all built on callbacks. So for example, you'll subclass activity and your activity will implement the onCreate method which gets called when it gets started. And then onPause is when they move on to another activity. So that's where you would save state and stop running CPU intensive stuff. And then there's an interface onClick. So for a button, you would pass in something that implements the onClick which might be your activity depending on how you set it up. So basically the whole thing is when stuff happens, some method gets called. And then Ubuntu would translate those to blocks. So basically instead of an onCreate and instead of defining an onCreate method, you call this handleCreate and whatever is in your block gets executed when that happens. And the way we do that is basically under the normal Java API, like if you're implementing an activity, your activity would directly subclass activity and then you would define the onCreate theme onPause, et cetera. But the way, what we do is we have this rubato activity in between. And what the rubato activity does is define all the methods that might be called back and all the code that's there basically says, push this on to Ruby and educate Ruby and give it the parameters and all that. And we do that with a very ugly .java.erb file to generate those with the rubato activity file. But you don't have to know that, you don't have to worry about that. So now getting into the heart of this, which is talking about rubato. So it started out just as a little IRB app. If you want to, you can download it right now if you get it in the marketplace scanner app, if you have an Android phone, if you don't have a barcode scanner app, I can't give you a barcode to download that. But you can always get it later, so I'll give you a link at the end. And basically Charles Nutter's on the .java.erb core team wrote it because he wanted to start playing with getting .java.erb on Android. It was just, it was an IRB, so just like an IRB on your phone where you could touch stuff in and it would show you the result. And then also you could save little scripts, like multi-line scripts and run them later. So that was useful and pretty cool and it allowed for some nice things, like if I'm out and I'm talking to people about movie and wondering about weird language quirks, I sometimes pull it out and try it on my phone, which is nice and I don't have to SSH into my server like I used to do on my iPhone. But it did have some limitations. You could only script activities, you couldn't do the broadcast receivers and services and other stuff. You couldn't ship an APK, which is the compiled Android package of your script. You would have to tell them, download the .java.erb, download the script, run the script, it wasn't, it's clean. And then also you didn't mess with the XML config, which meant, first of all, some of the layout stuff is easier to do with that. And also it meant that the .java.erb app just requests all the permissions that are possible. So then every script would have the ability to do all kinds of crazy stuff to your phone. And so this is, like it was a good starting point, but obviously they needed more. That's where I came in and this summer I worked on making the .java.core, which is for a full app solution. The goals of it are basically, I want it to be able to expose the entire .java API to your Ruby scripts, but at the same time, not actually require you to write a job. And then I mentioned there's gonna be plugins. So the idea is, I see it kind of like Sinatra, where it has a very tight core that basically just exposes functionality and stays out of your way. But then people can write plugins on top to make a nicer interface and make it easier to do certain things. And also I haven't done this yet, but I wanna make it so you have to write little to no XML, because no one likes XML. So the first demo that I'll do is just gonna be, I'm gonna show how you would create a starter app and then show what that, it gives you an app that does a little bit of functionality. So first of all, before you make a starter app, you're gonna need the JDK, obviously. You need JRuby, and one good way to install that is RBM, because an RBM also makes it easy to switch between JRuby and Ruby, and you can also switch between your versions of Ruby. It's pretty cool. You need the Android SDK, and then you probably wanna generate an emulator. You can develop straight on your phone and there are some advantages to that, but having an emulator is nice. You can just like, blow it away if you need to. You have root access to it, or you might not have root access to your phone, which is useful. There's some other stuff that's useful. And then once you've done all that, you just gem install robots on core. So then generate an app, and I'm not gonna go through all this, but the main important thing to know here is that the package, the Java package, is how Android differentiates between apps. So you need every app that you write to have its own unique package. You won't even be able to submit it to the market if there's already one with that package there, but it would overwrite if you were to just be working on an emulator on your phone directly, if you were installing the same package as one that was already there. And this is basically a dropping replacement for Android Create Project, which is the, if you were writing just a normal Android app, how you would generate that. So that's just nice. So this is, what that does is it basically creates, it gives you all the files that develop, that producing a normal Android app would give you, because it actually calls Android Create Project behind the scenes. But then it throws in a few other things, like it throws in those Roboto activity.java files, and a few other things like that. And then it also gives you asset scripts basically where you're gonna be spending all your time. It gives you asset scripts, Roboto.rb, which is the first thing you require, because it's what makes everything after that work. And then it also, back here I specified that I want the first activity that from when you launch to be called high activity, because this is just like a whole world-ish thing. And so that's why it's high in the score activity.rb. So just going through this, this is all pretty much blow and play. You require Roboto.rb, and then you ask for the view elements that you're gonna need. And then you basically put everything in your handleCreate method. You wouldn't have to, the blocks that follow, you could say activity.them and put it outside the handleCreate, but you don't have to say activity. If you put it in that. Then set title, just sets this world title bar on the top and it sets the text there. And this is a bundle, which basically just gives you a bunch of information. And that's the parameter that gets passed on Create. So Roboto just passes that on to you to do whatever you need to with it. So then getting into the more interesting stuff. Okay, so set up content is where you put all the content that's gonna be there when you start. So this is saying that the outermost view is gonna be what's called a linear layout, which basically just has other views within it and puts them linearly. In this case, we're saying we want it to be vertical, so it's gonna be one on top of the other. The other option would be horizontal, obviously. So it's like the first one that you put would be to the left and then move over. So here, what makes the text view is this column of text view element and then we're just stashing it in an instance variable so that we can use it down here. And then we say text, that's pretty obvious. Then here, we also want a button, which says, let me just show you guys this thing first. But I'll get through this, actually, honestly. And then there's a button with text, MX-birefied, it's a reference to an XKCD comic. And with wrap content, it just means that you want the width of the button to be the same as the text. Now I'll show you guys what this does so you can understand the last part. Now this is gonna be slow. When I was going to UI, this is gonna be slow. It's not that JRuby is that slow, but it's that we use a lot of reflection, what's called reflection, which is the Java equivalent of calling dot methods in Ruby. It gives you all the methods that something can use and it tells you their types, like what types they return, but how many parameters they take and what types those parameters are, whether it's public or private, all that good stuff. And the libraries on Dolvid, which is the actual VM, it's not quite a Java virtual machine, it's just a replacement for the Java virtual machine. The Dolvid reflection libraries, they've told us are really slow and eventually they're gonna make them faster, but it didn't make it into Gingerbread, the next version that's coming out now. So it's gonna be a while, we're gonna work on lessening our need for the reflection as well. So this is what you get. As you saw, there's a text reader button, so that's there. And then when you click it, two things are gonna happen. It's gonna change that question mark to an activation point, it's gonna put a notification down here. So see. And the way it does that is it says handle click and then it passes in the thing that gets clicked. And then this is just a check so that if something else got clicked and it, because if you were using that same on-quick method for multiple buttons or something, then you'd wanna see which one it actually was. And then you just say it's text reader set text and the toast is a notification thing that's built into Android. And then it just closes and this end closes the block. And then there's various ways to install, this isn't very interesting and you can find it on the review, but the main thing is to make sure that you're using JRuby's rake because it needs that to talk to Ant, which is the Java build tool that Android uses. And so the easiest way is to RVM use JRuby and then everything after that would be JRuby's rake, but you can also just do your VSS rake for every rake call. And then one cool thing is that there's rake update scripts so if you're using a Java app, you'll have to recompile the whole app every time you make a change. If you just make changes to your Ruby code, you can just run, and you have root access to the device you're using, it's a part of why you wanna use an emulator, then it can just copy the scripts on and then you don't have to recompile it and reinstall it and copy the scripts so that you can restart and see that it changed. So that can help you develop a little bit faster than you might be able to with Java. And now here's a little bit more of an involved demo that actually does things. So, I guess I'll share it all first. Basically, I wanted to do something with the hardware because that's what is interesting about mobile really. And so I made this demo, I'm gonna actually look in the photo booth so that I can show it to everyone. But basically what it does is it uses the accelerator to see when you move the phone and then it changes the background color when you move it, but not on a scale. So it's still right now, it's kind of a sense that it should change the professional, but it's still right now, but then if I move it, it's gonna have to see, you can see it up here too. So yeah, so let's see how we do that. All right, so this is a bunch of, so this is the same basically as what you saw before. And then we just have a text view in this case. It says shake or this one, you can actually see that. But then, and then there's a bunch of imports, we need more because we need like the sensors stuff and the color stuff. That when loss is the same as handle create, it's alias in that way. Whereas with a broadcast receiver, you have to know that it's on receive and with a service and I think it's also on create. When loss will work for all of those ideas just to kind of make people not have to think about what the actual underlying API is quite as much. So then we set title again, just like before. Then we, this gets us a, what's called a sensor manager. This one here. And then we ask for all of the accelerometers from that sensor members. So we ask for a list of the sensors that are type accelerometer. And then we check if it's empty. You can say on the emulator, you're not gonna get any accelerometers because there aren't any. And that way it won't totally crash it's empty. But otherwise, then we set an instance variable to be it so we can use it later. And then actually the most important thing, next, on resume also gets called on create. So you wanna put anything that needs to happen anytime you resume in there and we call both of them. So on resume, we're gonna register the listener which means that we wanna get notified when things happen and then on pause, we unregister that because we don't wanna know that they're shaking if they're not actually on our activity because we don't wanna be updating stuff. And then go ahead and see what happens when it does shake. It passes in the sensor event object. And then we make sure that it is an accelerometer because again, we might be using the same method to deal with some of the other sensor types like the proximity sensor. And then if so, then this is just a convenience one so we don't have to keep coming down values every time. And then this is to add a threshold to make sure that they're shaking it enough that we wanna change it because otherwise even as it was my unsteady hands sometimes we're shaking it. So then this is to make sure that's like taking the magnitude of the acceleration vector. And then this is the one that changes the color. So it changes to a random, this is a random color here, the color random 55 to 55, 55, 55. And then set, and then that makes a color, what's called a color drawable. And then it sets that to be the background drawable. You don't need to know all the specifics that are necessary. If you would look in the Android documentation, you were actually trying to write this. And so that's like, it really isn't that much code. And it's a little bit, probably a little bit simpler than it would be in Java and it's very easy. So, moving on. One thing that you probably noticed is that it was slow. I already had, this one, the one I did on my phone wasn't slower than it started out before. The one before was slow. A little bit slower than it would be on a phone. I think I figured that a whole world takes around seven seconds on a phone but it's still not really acceptable to actually use it this time. But it is possible to get you some of the benefits here but actually usable today and fast is what's called Mira. Which, this is a language also by Charles Nutter. It's a JVM language, at least from now, although he actually has it set up so it's gonna be pretty easy to say, write a C++ backend or a .NET backend as well which is one of the benefits to it. The goal is to have as much of a Ruby-like syntax as possible. And you'll see that in a second. It even has closures and all that stuff, meaning blocks. But it's statically typed and the big thing here is it has no runtime dependencies. So whereas a Hello World app for Rubato is around 10 megabytes and it still has to ship with the JRuby jars, a Mira Hello World app is, and that also slows it down because it has to start all of JRuby just to do these little things that you pretty much can write yourself in Java. The Mira, it compiles straight to either to Java code or to Java Lake code and compile Java. So that means that it's basically as fast as Java you would write. You'll see it basically generates the Java you would write but not quite. So it's got the speed, it means that you don't have this big this big startup value. You have a big jar that's slow to load for something when you're just doing Hello World or something small like that. It just grows as Java. Anyone. So this is the Hello World in Mira. It is exactly the same as it would be in Ruby. You get instance variables, you get the string inserting, you get all that. And then slightly more complicated would be Fibonacci here. The only diff from Ruby is that you have to tell it that it takes a fixed num which then translates to the right kind of integer on the back end, depending on which back end you're using. Note that you don't have to tell it your return type because it can infer that. So that's pretty cool. And the Java code that it generates is really not that scary. It's a little bit weird and this whole thing will be on one line but it didn't fit on my slide. But except for the fact that it's using the ternary operator and it's all on one line that's pretty much how you would write this in Java. So that's, and that means that it's gonna be just about as fast because that's how you'd write it in Java. So demos of that. Techno-Rancy wrote this thing Garrett which I will not show you the code to. It's fairly long, which just has a bouncing ball. But what I did is I just took, it's really pretty much just a straight Android application but he added one task to amp the build tool to compile the Mira to Java code before doing the rest of the build. But I just, I basically stole that and wrote, more or less rewrote the hello world that I just showed you in Roboto in Mira. I'll show it, I won't show it to the screen but you guys can read it. So this is what a hello world app which I'll show you would look like in Mira. So first of all, look at how fast this loads. It loads basically instantly, just like a Java on wood. And then I didn't do toast, I didn't do changes by the size of this, that's a little bit of a pain, but you can see it, it does the same thing, and this looks, so you do all these imports, some of these imports are things that we did in the Roboto that RB did and some of them are things that RobotoActivity.java did. And then you see it's pretty much, it's a little bit different, you can't, you don't get like passing in hashes and stuff. You could also change some of this layout to be in XML and that, they claim it's easier but I'm not a huge fan of XML. But it really is pretty self-explanatory and it doesn't look like Ruby. You have this block here, and it's not that complicated and yet it still feels like Ruby, you don't have to work out your right pinky so that you can get all the semicolons in, et cetera. But one thing which is kind of, if you look back at what this looked like, this does feel more like it's all blocks and stuff and that also means it's a little bit easier to build abstractions up from this than you could write blocks that call out their blocks. And so that's one of the things I'm hoping for with Roboto is that plugins will be, and we pretty easily write a plugin that's powerful and makes things easier. So moving on, one thing that you might have heard of is what's called scripting layer for Android which is another way to write Ruby code for Android apps. These are quotes from their website. Scripts have access to many of the APIs available to full-fledged Android applications, but note that that doesn't say all. And they aim for a greatly simplified interface. They do have an impressive list of languages, big support including TCL and Lua and Beanshell and they are planning to add even more, which is cool. And you might have seen, there was a blog post a few months ago that had a spy camera app which was pretty cool. They vended in Sinatra and then they had the app. You would go to your phone's IP like usually over wifi you can do that. And then what it would do is it would take a picture with the camera and then render you a view that served you that picture. And that was pretty cool and it was really cool code. It took about 30 lines to do that. But, and so it is a great project but I think that it's not the best approach at least for what I'm aiming for. I want Roboto to expose the full Android API so that once we get speed under control people can use that for any app they want to. And even things where really you care about being able to have full freedom you can do with Roboto. So it seems like Scripting Layer for Android is more for hobbyists and playing around with it. Whereas I'm aiming for exposing everything in that for allowing me to do more even everything basically. And then ways for Roboto to be better than the other options. First of all Rui, second of all break up the script as cool as I can. And third of all the abstract is the ability with this block basically you could write plugins pretty easily they just call their blocks and like make a whole bunch of text using. It's a little bit more powerful because it's Rui and because it's closures and all that. And then ways that you can help. First of all just use it and then complain when things are broken or confusing because there's probably some things that don't work that well that we just don't know about because there aren't that many people using it. One more block would be when something's confusing you contribute documents. So like if you find something confusing but then work your way through it and ask us an IRC then you could go to the Wiki and update that and update them to make it more clear for future people. And then one step up would obviously be forking it and contributing to the actual code. And then soon also have a plugin architecture so that you can write plugins and upload that. I'm going to go fast but that's basically it. Thank you a lot to Charles Nutter because first of all he is much of the reason why JRuby is as mature as it is. So without him we wouldn't even necessarily be able to do this and also he was my mentor for Ruby Summer of Code. Thanks for all the Ruby Summer of Code sponsors because that's how I managed to do this. And also early contributors and you probably haven't heard of them Scott Neuer, Jim Burkele, Jim McAvron who all been pre-active in pushing this and working on code. And if you have questions you can ask me now or find me after this, I'll be around for the next two days. And then all the everything I referenced here this is my slides, the demos, like links to Roboto and stuff are all going to be on my blog. Actually I already are and that was really fast but I'll take questions. Building path to back in on it like roads or say a kindness catch port for Android or you're simply using typically the SQLite 3. What do you ask me? What type of backend is typically used for the apps on this for storage? Right now, not much. You can write to the files, which would be the main thing but we're going to add as we, we always support a few of the classes right now but as we, it shouldn't be too hard to move on to support all the classes and that includes the SQLite helper class whatever it's called, the latest SQLite. So there's no use of anybody using roads? Roads is kind of separate. Yeah, so it's a Ruby, I wondered if there was any written between those two Ruby systems. Not to my knowledge because roads like, you write a Ruby in that, that compiles it down to the job or the other. Here you're actually interpreting the job on the device or on the Ruby on the device. Roads is totally separate is the journey to that. How do you push it? So what about the rest of the Android SDK? What do you mean? Stuff in Eclipse, the emulator, the logic. Well, the emulator, I mean. Building a resource in the SQLite. All right. Well, there's some, I'm, I mean, I have rake tasks and stuff that the Robots of command one tool can do for some of the stuff that Eclipse would do. I guess that'll expand in the future. For the emulator, it's not that hard just to generate yourself really. So that's the short answer, I guess. Were there any kind of like a testing framework? And kind of that's like the worst part of Android development right now. It's hard to test this. I haven't really thought about it. Like, obviously eventually that would be good, but I don't really, I think first thing is you get it fast enough to actually use and exposing the entire API. But then yes, testing would be good. If you want to write that. No. For someone like just starting to develop Android, why would you recommend using Roboto over like just going in with Java and that's the game? Because you're like Ruby? And also because, as I said, eventually, I think that we'll be able to make a simpler interface between the block-based interface that we have and possible plugins on top that make it even easier. But I mean, if you want to write it out right now, don't use Roboto, use either Mira or Java. And Mira basically is Java. In the end, we'll give you all the things that Java would give you pretty much. Just like your examples, you have a pretty heavy DSL in your Roboto. Yeah. Just the subclassing. Yeah. What was, when designing your Roboto, why did you decide to go for DSL instead of just using some classes? Well, the DSL is already there, but there's also, I think it's, Charlie, quickly for a moment. I think it's not actually possible on the phone to subclass, to have a Ruby class, subclass, Java classes, right? Because it needs to generate bytecode to do that and we can't generate Dalvik bytecode at the time. The way the Android API works is that you write Java code. It gets compiled to Java bytecode. And then the Android tooling compiles it to Dalvik bytecode, but you can't do that on the phone. I guess we could, but we don't have support for it yet and there would be a pain to add. So with that not working, the only real option is to have these generated Java files and pushing it along to a calling a Ruby script. Other than the fact that you can't extend an activity, you don't necessarily have to use this DSL. You can't just have a script that gets the dollar sign activity thing and just starts calling. But you can go through and do the, basically the same thing in Mira. You just need the extra little help for getting an activity. So you had mentioned before about Java reflection being slow. And that you're working to improve the performance and the contributions. So what is the plan in terms of this? Well, I think, we haven't talked about it too much, but I think basically trying to do it ahead of, like doing the reflection ahead of time and have it cached essentially would be the goal, but it's a little pain. We're not totally sure. All right, I remember you went on music with the package of JRuby and the application. There was quite a large size package. Not really. We thought about, we've talked about, like trying to take out classes that you like certainly wouldn't need, but it's not yet. The Android world is that Google, like basically just drops their next big thing. They've worked on it in secret for a while and dropped it on the floor. And that did you guys during the talking? Not really, just the way we have it. We generate, we use reflection to generate the files, so which means that it just goes through and asks for the methods and then pulls them all in. So it's pretty much, we can generate that in like five minutes or less. So not really. But I mean, if you want to plan how to, what you're going to do with your app, then obviously that's a little bit pain.