Android emulator is too slow. And here’s the solution…

Why can’t we have nice things?

I’m an iOS developer, and anyone else who worked with iOS knows that iOS Simulator is awesome. Fast, reliable and pretty. Sure, sometimes it doesn’t work very well, but it’s pretty close to perfect. I would add some other features, such as, using your Mac’s iSight as a camera for the simulator. -Apple? Please?-

Needless to say that to someone who it’s used to work with iOS Simulator, the Android Emulator is a *very* big disappointment. But why is the Android Emulator so bad compared to the iOS Simulator?

Emulator vs Simulator

The terminology is: Simulator is a system that behaves similar to something else, but the implementation it’s not necessary the same. An Emulator in the other hand, is a system that behaves exactly like something else. Basically:

– iOS Simulator: Runs native code on you Mac, compiled for x86 architecture.

– Android Emulator: uses QEMU to run ARM, emulating the hardware.

Click here for an interesting reading about the subject.

Enters AndroVM

You can improve the experience using AndroVM and VirtualBox. In a nutshell, AndroVM is a VirtualBox Android image ready to use, and works pretty well 😉

– First open AndroVM download page clicking here and download androVM_vbox86p_4.1.1_r6.1-20130222-gapps-houdini-flash.ova file. (if you want the tablet version, download the vboxtp version.

– Download and install VirtualBox for your system clicking here.

– On VirtualBox, go to File -> Import and select the .ova file you just downloaded.

Import .ova

– I like to clone the image, so I can mess around with the system without any problems, so, right-click on the virtual machine and select “clone” and when prompted, select “full clone”.

clone

– Right click on the image, click on Settings. Open the Network tab, click on Adapter 1, check the “Enable Network Adapter” and attach to your adapter. This is for “adb” to connect to your virtual box image.

adapter

– Now just run your machine and play around with the device, compare it with the standard emulator and see how fast it is 🙂

android

How to debug your application

Now that you have your VirtualBox setup, it’s time to actually use it to debug your apps. First, on your Android Emulator, open the AndroVM app. It should be the lower left icon on your device screen. You should see the device network IP there.

androidIP

– Open your eclipse project, for this example, I just created a standard “Hello World” project.

– Open the “Run Configurations” panel, click on “Target” tab. Select to “Always prompt to pick device”.

– Run your project, you should see this screen

eclipsePrompt

– Now, open your terminal, and type “adb connect THE_IP_OF_YOUR_DEVICE”

– After doing that, note that the Eclipse prompt now shows your device on the list.

eclipseDevice

– Select your device and click “OK”.

– That’s it, you should see your app running on your brand new emulator 😉

androidTest

Conclusion

This is definitely not as fast as the iOS Simulator but it’s a huge step forward. With this setup you don’t need to always have thousands of devices with you neither wait hours to have the emulator to boot up.

ps.

– If you want to use the Android back physical button, hit “Esc”

– If you want to use the Android menu physical button, hit “F1”

Enjoy 🙂

Advertisements

Where am I? Know how to get your location using CLLocationManager

Yey, here I am again. I didn’t update my blog for a while, I was really busy with some projects, hmm, in fact I’m busy right now, but I want to write a new post \o/.

One thing that’s really useful and simple to do using the iOS SDK is getting the user location to do whatever your want (well, not whatever you want, stalkers, but you got it). So, we will need something to help us out to get the user location, giving a quick look at the documentation you can find the CLLocationManager Class.

The CLLocationManager class defines the interface for configuring the delivery of location- and heading-related events to your application.

And let’s see, how do we use this class? Take a look at the example bellow:

locationManager = [[CLLocationManager alloc] init];

locationManager.desiredAccuracy = kCLLocationAccuracyBest;

locationManager.delegate = self;

[locationManager startUpdatingLocation];

Yep, that’s it, 4 lines of code and the locationManager now is looking for your location, pretty cool huh? You may ask “What is this desiredAccuracy property?”, well you should look at the documentation, it’s there for answer all our questions about the universe, but I’ll be a nice guy and copy it here

“You should assign a value to this property that is appropriate for your usage scenario. In other words, if you need the current location only within a few kilometers, you should not specify kCLLocationAccuracyBest for the accuracy. Determining a location with greater accuracy requires more time and more power.”

This property determines the precision of your CLLocationManager, it’s a const with 6 possible values, you should look at every one and use the one that best fits your needs.

OK, now our locationManager is updating your location, but how do we retrieve it? If you read the code carefully you may have seen that there’s a delegate assigned to self, right? This is how we will get our location. There’s 2 important delegate methods:

– (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation ;

– (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;

The second one is used in case of some error, for some reason your device failed to retrieve your location, and the first one will give you the CLLocation, that has the latitude and longitude plus other cool things. This delegate will be called every time that the locationManager gets a new (and better) location

That’s all you need to get the location of the user, but latitude and longitude are boring, OK, not really lat and lng rocks \w/, but let’s do something more useful with them…

One More Thing…

We have the location, latitude and longitude, with a few lines of code, but let’s transform this in a real address so it’s human readable. Again, reading the documentation we will find the MKReverseGeocoder

“The MKReverseGeocoder class provides services for converting a map coordinate (specified as a latitude/longitude pair) into information about that coordinate, such as the country, city, or street. A reverse geocoder object is a single-shot object that works with a network-based map service to look up placemark information for its specified coordinate value.

And how it works? It’s pretty similar to the CLLocationManager class, just 3 lines of code and the reverse geocoded starts the job

reverseGeocoder = [[MKReverseGeocoder alloc]  initWithCoordinate:currentLocation.coordinate];

reverseGeocoder.delegate = self;

[reverseGeocoder start];

And just like the CLLocationManager, we need to implement the delegate to get the address, and they are:

– (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark ;

– (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error;

The first delegate will return the MKPlacemark, that has the address, so you can access the thoroughfare with the property thoroughfare like placemark.thoroughfare.

I did a sample project that search for the user location and when it finds the location the MKReverseGeocoder start to search for the user address. In my example I have a condition that the reverse geocoded will only begin if the locationManager finds a location with accuracy range of 200 meters.

if (currentLocation.horizontalAccuracy <= MINIMUM_DISTANCE) {

[self startReverseGeocodingWithCurrentLocation];

}

Download the Source Code Here.

Have fun 🙂