Wednesday, October 10, 2012

Enter the DROID World!!

Well quite frankly i'm late to the game, but here i am, getting my hands dirty(or wet or whatever you might call it) in the world of android. This post will focus on how to set up the android SDK, setting up ADT for eclipse as well as an introduction to the structure of a typical android project using an example. Lets get going (said in a robotic voice of course)...

First of all you need the Android SDK to get going. Download the relevant version for your platform. Currently it supoprts Windows, Linux and Mac. All right, got it done? Awesome, lets see the minimum you need to get started. Note that when you run the installer you will be presented with the following screen;

Android SDK Manager
The rows i have marked with an arrow are the minimum elements you need to download in order to get started. Of course here i have presented my SDK manager in which i have installed almost everything. But that takes too much of time, and i know all of you do not have much time to spare. So just download the marked elements and lets get this show on the road!!!!

Got everything installed? Great, now lets set up our eclipse platform to start creating awesome android applications. Note that you require Eclipse 3.6 or higher to get the ADT ( Android Development Tools) plugin to work.

Go to install new software and add the location of the ADT plugin which is http://dl-ssl.google.com/android/eclipse . You only need to download the Developer tools from the ADT plugin because you will only need the NDK in a few instances. The NDK is the native development kit which allows you to program at a lower level using C language specifics. This post will only focus on the Android SDK.

So once you get that done you are ready to roll my friend. Before that i would like to mention a few things that are available to you after installing the Android SDK. You will have the SDK Manager and the AVD manager. The SDK manager will show any tools or APIs you need to download and you can use this tool to upgrade you environment as and when you need. We will get to the AVD manager when we look at the sample application.

In Eclipse, go to New->Other->Android->Android Application Project and follow the steps. Note that in the first screen you will have an option to specify the minimum required SDK. This signifies the minimum android SDK your application needs to run. Select the option "Create Activity" and select the blank activity option. Give it a name and finish off the application creation process.

Now you will be presented with a structure as follows;

Lets take a look at what each folder is for.

assets : any property file, databases, text files or the sort which you want to bundle up with your application can be put here. This can have its own folder hierarchy within it self and you can read those files in the usual way you do file reading in java.

bin : contains the various files built by the ADT plugin. It will contain the .apk(Android application package file)

gen : this folder contains mainly two files that are compiler generated. Which are R.java & BuildConfig.java. I will explain more about he R.java in a bit. It is best not to edit these files as these are anyway generated on each build.

libs : Contains the android jar that exposes the android APIs required for development. Note that in our application it uses the android-support-v4.jar which is the support version library that allows you to use newer APIs whilst having support for older Android Operating systems.

res : this folder contains all the resources required by your application such as images etc. You can categorize according to various screen resolutions, languages and OS versions. The layout folder will contain the XML file that allows you to define your UI element specific to your activity. The values folder allows you to define language entries in such a way we use .properties files in normal java applications to support different languages. More information can be found here.

src : contains the source files of your project.

AndroidManifest.xml :  The manifest will define the name of the application, icon to be displayed, the various activities used, Permissions required etc. The version code is set to "1" initially. This code is used to determine whether your application has an upgrade available or not. Best practice is to increment the value on each release.

Within the manifest you can see an entry such as android.intent.action.MAIN. This signifies that the activity we just created is the main entry point of the application ( such as the main method in a java program).

R.java : This file is automatically generated and it is recommended that you do not change this file manually because anyway when you do any changes in your project, ADT will generate this file. This file provides access to the resources in your application in a programmatic way so that you can access your resources in a unified manner.


Let us open the blank activity that we just created. Ok the app here does not do much. But i just wanted to introduce the various elements that make up an android application and to jump start development. Within this sample what i show is how to call another activity from your main activity.

Let us first see the xml file pertaining to my main activity.


 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="107dp"
        android:layout_marginTop="134dp"
        android:text="@string/next_activity_btn_name" 
        android:onClick="actClick"/>

</RelativeLayout>

As you can see nothing major here. Just one button which i have defined. The name of the button is defined in the strings.xml in order to make the application localization friendly. Also i have defined an onclick functionality. Let us see how the onClick method is implemented in my main activity;


 
package com.example.droidworld;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;

public class DroidMainActivity extends Activity {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_droid_main);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.activity_droid_main, menu);
  return true;
 }

 public void actClick(View view) {
  startActivity(new Intent("com.example.droidworld.NextActivity"));
 }
}


You can see that the name of the on click method is the same as what i defined in the XML file. Also the method takes on the View class as a parameter. Within this i use the method startActivity() which enables us to call another activity. Any name can be given here which should correspond to the name given in our application's manifest.xml file. Let us see how we have defined this in our manifest;


 
    <activity
            android:name=".NextActivity"
            android:label="@string/title_activity_next" >
            <intent-filter>
                <action android:name="com.example.droidworld.NextActivity" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>


Within the intent filter tags, the name given for the attribute android:name should correspond with the name given within our Intent() method within the startActivity method call. android.intent.category.DEFAULT  allows another activity to call this activity. You can also get away by not defining intent filters if the activity you are going to call is within your own project. If that is the case then you call the activity directly as such;


 
startActivity(new Intent(this, NextActivity.class));


One thing to note here is that if you want to expose your activity to other applications, then you need to expose it using intent-filters.

That about winds up the introduction to the droid world. I myself am pretty new to this, so if you believe some of what i said in this post is invalid or requires changes, please do leave by a comment which is much appreciated.

You can download the sample project from here. You just need to do a Run->Android Application and you are good to go. Make sure to set up an AVD manager before running the application. The AVD manager creates the emulator on which your application is deployed. Create an instance by going to Windows->AVD Manager. The rest is intuitive so i will not go into detail. If you have any issues please do let me know and i will be glad to help.

I will follow up this post with a few other articles to depict various features available.

Thank you for reading and have a good day. And from words of the Terminator "Hasta la vista "

Cheers!!

Tuesday, October 9, 2012

Locking with a semaphore : An example

Concurrency is one aspect that brings along interesting challenges along with it. If not correctly handled, it brings about race conditions that will baffle people because those issues just pop up from time to time and work flawlessly sometimes.

The Java language gives many ways of handling race conditions when dealing with concurrent threads accessing a common resource. Some include;


  1. Using the volatile keyword
  2. Using classes available in java.util.concurrent and java.util.concurrent.atomic 
  3. Synchronized blocks
  4. Using a Semaphore
Of course there might be many more that i might not be aware of. For today, the example i want to show you all is the one using a Semaphore. This was introduced from JDK 1.5, and provides the developer with the ability to acquire and release locks in a seamless way. Also the example i will be showing is a hypothetical scenario which i used just to depict what can be achieved using a semaphore and therefore please do not look at the intrinsic details of the code :)..

So the scenario as such, there is an in-memory cache holding objects of type "Person". Users can insert and retrieve records using the cache. The issue here is we are going to control concurrent access to our in-memory cache using semaphores. Now i do not want to bore you with more text so lets get to business and show some code;


 
import java.util.concurrent.Semaphore;

/**
 * This class will allow thread to acquire and release locks as required
 * 
 * @author dinuka.arseculeratne
 * 
 */
public class PersonLock {

 /**
  * We do not want multiple lock objects lying around so we make ths class
  * singleton
  */
 private PersonLock() {

 }

 /**
  * Bill Pugh's way of lazy initializing the singleton instance
  * 
  * @author dinuka.arseculeratne
  * 
  */
 private static class SingletonHolder {
  public static final PersonLock INSTANCE = new PersonLock();
 }

 /**
  * Use this method to get a reference to the singleton instance of
  * {@link PersonLock}
  * 
  * @return the singleton instance
  */
 public static PersonLock getInstance() {
  return SingletonHolder.INSTANCE;
 }

 /**
  * In this sample, we allow only one thread at at time to update the cache
  * in order to maintain consistency
  */
 private Semaphore writeLock = new Semaphore(1);

 /**
  * We allow 10 concurrent threads to access the cache at any given time
  */
 private Semaphore readLock = new Semaphore(10);

 public void getWriteLock() throws InterruptedException {
  writeLock.acquire();
 }

 public void releaseWriteLock() {
  writeLock.release();
 }

 public void getReadLock() throws InterruptedException {
  readLock.acquire();
 }

 public void releaseReadLock() {
  readLock.release();
 }
}

This class will handle the process of obtaining and releasing locks required to make our cache thread safe. I have used two separate locks here for reading and writing. The rationale behind this was to allow users to read data though it might be stale at the time of reading.

Note that i have used "ten" here which denotes that ten thread can simultaneously obtain locks and access the cache for read purposes. Next up you can see in the write lock, i have used the "one" which signifies that only one thread can access the cache at a time to put items to it. This is important in order to maintain consistency within the cache. That is, i do not want multiple threads trying to insert items to the map which would result in unpredictable behavior ( at least in some instances). There are mainly two ways by which you can acquire a lock using a semaphore.

 1. acquire() : is a blocking call which waits until the lock is released or the thread is interrupted
2.  tryAcquire() : is a non-blocking call which will return immediately and return true or false signifying whether the lock was obtained or not.

Here i have used the blocking acquire call because i want the thread to wait until the lock is available. Of course this will depend on your use case. You can also define a timeout period in the tryAcquire() method so  that the thread will not wait indefinitely for a lock.

Next up the storage class below shows how i have used the lock class to insert and read data within the cache.




 
import java.util.HashMap;
import java.util.Map;

/**
 * A mock storage to hold the person objects in a map
 * 
 * @author dinuka.arseculeratne
 * 
 */
public class PersonStorage {

 private Map<Integer, Person> personCache = new HashMap<Integer, Person>();

 private int counter = 0;

 /**
  * This class is made singleton and hence the constructor is made private
  */
 private PersonStorage() {

 }

 /**
  * Bill Pugh's way of lazy initializing the singleton instance
  * 
  * @author dinuka.arseculeratne
  * 
  */
 private static final class SingletonHolder {
  public static final PersonStorage INSTANCE = new PersonStorage();
 }
 
 /**
  * Use this method to get a reference to the singleton instance of
  * {@link PersonStorage}
  * 
  * @return the singleton instance
  */
 public static PersonStorage getInstance()
 {
  return SingletonHolder.INSTANCE;
 }

 /**
  * Inserts the person into the map. Note that we use defensive copying so
  * that even if the client changes the object later on, those changes will
  * not be reflected in the object within the map
  * 
  * @param person
  *            the instance of {@link Person} to be inserted
  * @return the key which signifies the location of the person object
  * @throws InterruptedException
  */
 public int putPerson(Person person) throws InterruptedException {
  
  Person copyPerson = person.copyPerson();
  personCache.put(++counter, copyPerson);
  
  return counter;
 }

 /**
  * Here as well we use defensive copying so that the value of the object
  * reference within the map is not passed in to the calling party.
  * 
  * @param id
  *            the id representing the location of the object within the map
  * @return the instance of the {@link Person} represented by the key passed
  *         in
  * @throws InterruptedException
  */
 public Person retrievePerson(int id) throws InterruptedException {
  PersonLock.getInstance().getReadLock();
  if (!personCache.containsKey(id)) {
   throw new RuntimeException("Key is not found");
  }
  PersonLock.getInstance().releaseReadLock();
  return personCache.get(id).copyPerson();
 }

}

Obviously the code will work without the locks as well, but the issue is that the application will be inconsistent and provide different results at each run. This is not something you want your application to do and hence with locks you guarantee your application works consistently.

And lastly a small test class to show how it will behave; not that in here we obtain the lock before calling the putPerson() method and release the lock within the finally block in order to guarantee the release of the lock.


 
/**
 * A test class to demonstrate the locking at work
 * 
 * @author dinuka.arseculeratne
 * 
 */
public class TestLock {

 public static void main(String[] args) throws InterruptedException {

  Thread t1 = new Thread(new Runnable() {

   @Override
   public void run() {
    
    Person p1 = new Person(1L, "Test1", "XYZ");
    try {
    PersonLock.getInstance().getWriteLock();
PersonStorage.getInstance().putPerson(p1);
    } catch (InterruptedException e) {
     // Exception handling need to be done
     e.printStackTrace();
    }
   finally{
          PersonLock.getInstance().releaseWriteLock();
    }
   }
  });

  Thread t2 = new Thread(new Runnable() {

   @Override
   public void run() {
    
    Person p2 = new Person(2L, "Test123", "ABC");

    try {
     PersonLock.getInstance().getWriteLock();

     PersonStorage.getInstance().putPerson(p2);
    } catch (InterruptedException e) {
     // Exception handling need to be done
    }
 finally{
          PersonLock.getInstance().releaseWriteLock();
    }
    
   }
  });

  t1.start();
  t2.start();

  System.out.println(PersonStorage.getInstance().retrievePerson(2));
 }
}

That concludes my short introduction to using Sempahores to make your code thread safe.For anyone who wants to play around with the code, you can obtain it from here. Try to remove the locks in the Storage class and see how it behaves on each run. You will see possible race conditions taking place.

Appreciate your comments and feedback on the same as always and thank you for reading.

Cheers....

Monday, October 1, 2012

As my journey through IT continue

So recently i just surpassed the 5+ year mark in my career. So i dwelled upon my journey so far and wanted to pen it down ( well key it down in this instance :) ). And this is how my story goes;

Just after Uni, i started working at a start up company specializing in stock trading applications. Even today if someone asked me what was the most challenging thing you have worked on, this company will always be in the top 10. After uni, for a guy looking for a challenging career, this was just what the doctor ordered. Loved every bit of work, and also the people were very courteous and helpful in every way. From the CEO to architect to the tech leads, if you ever needed help with anything, they were always there for me.

Got my very first & only taste of C++ right in this very company. Now that was one heck of a language i must say. Keeps you thinking of every intrinsic detail. Of course looking back it might be overkill comparing with some languages now, but hey for a person just out of Uni, these are interesting stuff. Though i had an apprehensive nature on joining, the people at this company really made it easy for me to settle down.

Thoroughly enjoyed the late nights, trying to figure out why something that seems fine is just not working on production, learnt what true team work is all about.

Then came the time for me to move in pursuit of better opportunities, though my heart up until this date is still with this company because the people there were such fun loving people. The CEO was the key role whom i still look up for. My idol in the local IT sector.

One thing i never stopped was learning. Continuous learning is what keeps your value on par with the industry. If you lose your value, then your not an asset to the company any more. I wont say you should go and learn every technology or language that pops up in the news, but its more or less like engaging in the stock market. If you are not in the know of the stock movements, your bound not to capitalize on the opportunities that might arise in the future.

Few things i have observed on my journey is that often time many people focus just on the money factor. They enter the industry thinking it is a one stop stairway way to wealth. Don't get me wrong, money is important, but entering the software industry with just money being your goal and sole purpose will not take you much far.

What i always believe in is that you should learn from each experience, and with experience and time, money will come. Some people give me this incredulous look when i say that to them. But that reality i have lived is what i tell them. Believing it or not is up to them :).

And then i meet a few rock stars who are solid and sound technical people, but lack communication skills or most often have a very bad case of Asperger syndrome. Often times i see these people rise up early in their career but then be victims of ostracism due to the fact that they just do not understand that at the end of the day, without a team effort, a company will not thrive.

One thing i always believe is humility. This was one of the many gifts i inherited from my father. No matter how far you may go, you should never forget how you got there. A very important saying my father taught me was

                 "Be careful not to step on others' toes on your way up,
                   You do not know who you will meet on your way down ".

Another version goes as;

                  ""Be careful whose toes you step on today because
                  they might be connected to the foot that kicks your ass tomorrow!!"
                  -Brandon Ramos"

 No matter what you achieve in life, what i believe is that the world holds together because of the love and relationships we have with each other we meet on our journey through life.

I give my 100% to anything i set my heart to because it is when you truly believe in something that you will actually set out to achieve it. And so continues my life in the software industry with many more challenges ahead which i gladly look forward to.

All i can say is that it has been one heck of a ride up until now, and what ever path God chose for me i shall walk since "I can do all things through Christ who strengthens me. Philippians 4:13"

Have a great day everyone... Take care and God bless