Saturday, February 23, 2013

DZone, your too sweet!!

And the wait is finally over, because today i just received my DZone Goody pack. Got a mail from the local postal office saying it was held at the respective post office and wanted me to come and collect it. I actually had no idea that it was the goody pack that arrived. My eyes simply lit up once i saw the box. WOW... could not wait until i got home to open it up.

And this is what i found;





Loved each item in the pack specially the t-shirt and the USB drive. Ofcourse the missles were pretty darn awesome too ;)..

Thank you so much DZone and this definitely is a push the right direction for me to continue contribution even more to your esteemed community.

Cheers


Saturday, January 12, 2013

Dev vs QA, should there really be a distinction?

We had our scrum of scrum meetings last Wednesday where all scrum masters meet up with our line manager to discuss issues, bottlenecks and success stories of our previous sprint. One issue highlighted was the fact that sometimes the QA(Quality assurance) personnel are clogged up with testing issues that are in the "Ready for test" stage. So one idea that came about was that given the fact that some developer resources are freed up during this period, that it would be better off putting up some of their time to test the issues.

My first reaction was "HELL NO!!". My primary concern was that a developer will never have the mindset of a QA personnel when it comes to testing since he/she would always have a stringent approach on how to view the application. Also there is a notion among a few that doing QA is so "feminine" (again this is what i have observed and would differ from the context where i am in). So i took a step back, took a deep breath, turned off my dev-mode and looked at the suggestion in a more holistic manner.

I'm a person who loves to acquire new knowledge, be it from reading books, journals or simple through other's experience (young or old). So for me this turned out to be a way i could grab some new knowledge. Specially about software testing and quality. Now i know writing unit tests count for something, yet that is at its name dictates a unit level testing. When it comes to quality assurance, that is a whole new beast in its own right. Now you have to think in the perspective of how users interact with the system and not in the way you wrote the code for the application to behave.

By learning the art of QA testing, i believe that it would enable me to write more quality code since i would have the user's mindset and approach when testing my own code before i push it in to version control. Also in scrum the notion is that we as a team commit to deliver a set of issues we plan for a particular sprint. Hence if i do development or testing doesn't really matter since either way i am contributing towards helping my team achieve our team's commitment. It should not be thought of as someone else's responsibility. It's the team's responsibility to deliver the planned work on time with quality.

But such a change of mindset does not happen overnight. Its not merely about you going and telling each developer that he/she has got to start testing issues from the next sprint. I believe of leading by example. It's a win-win situation since i gain an extra skill of quality assurance testing whilst the team will emancipate themselves from the notion of thinking testing is not a part of responsibility of a developer (Hopefully). Change needs time to sink-in, and you cant coerce anyone into embracing change, but you can influence them through your actions.

What if some people never gets on board with this idea? Well i would say its their loss and my gain since in this dynamic business context we live in, i strongly believe if you try to stay with the pack, you will always be where you are right now.

Break away from restrictive thinking, like Lion-O of thunder-cats tells his awesome sword to give him sight beyond sight, we should strive to look through the limitations and think in ways we usually would not and get our lazy bottoms out of the conservative thinking mode.

That my friends brings me to the end of my note for the day. I hope you enjoyed reading it. Please do leave by your comments, views, criticisms and thank you for taking the time to read through.



 

Monday, December 17, 2012

Checking out what is new with Servlet 3.0

With the JEE6 specification hitting the market, some major changes have taken place with respect to how you would approach developing applications in the enterprise application world. In this article i would be touching upon a few changes that were done with respect to web application development.

First things first, say good bye to the web.xml deployment descriptor (at least for parts of it). Well its not like it is deprecated, but with the rise of the usage of annotations and their usage, the new specification allows us to define our configuration using annotations, though some thing such as welcome file lists, context params etc will still need to go inside your web.xml . Annotations available for use are;


  • @WebServlet
  • @WebFilter
  • @WebInitParam
  • @WebListener
  • @MultipartConfig
In this article i would be checking out the @WebServilet and @WebFilter annotations. Let us see how we would usually map a servlet in the web.xml era;





    <servlet>
        <servlet-name>myservlet</servlet-name>
        <servlet-class>com.example.MyServlet</servlet-class>
    </servlet>
 
 <servlet-mapping>
  <servlet-name>myservlet</servlet-name>
  <url-pattern>/hello</url-pattern>
 </servlet-mapping>

With the Servlet 3.0 spec, now configuring a Servlet is as easy as annotating a class that extends HttpServlet. Lets see how that looks like;


@WebServlet("/student")
public class StudentServlet extends HttpServlet{

 /**
  * 
  */
 private static final long serialVersionUID = 2276157893425171437L;

 @Override
 protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1)
   throws ServletException, IOException {
  StringBuilder response = new StringBuilder(500);
  response.append("<html><body>").append("Registered Student : ").append(arg0.getParameter("txtName")).append("</body></html>");
  arg1.getOutputStream().write(response.toString().getBytes());
  arg1.getOutputStream().flush();
  arg1.getOutputStream().close();
 }
}

All you need is the @WebServlet annotation. In order for this to work, the class should reside either in the WEB-INF/classes folder or within a jar residing in the WEB-INF/lib folder. Next up lets see how we would configure a filter with annotations.


package com.blog.example.servlettest;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

@WebFilter("/student")
public class StudentFilter implements Filter{

 @Override
 public void destroy() {
 }

 @Override
 public void doFilter(ServletRequest arg0, ServletResponse arg1,
   FilterChain arg2) throws IOException, ServletException {
  
  if(arg0.getParameter("txtName")==null || arg0.getParameter("txtName").isEmpty())
  {
   arg1.getWriter().append("Invalid name supplied");
   arg1.getWriter().flush();
   arg1.getWriter().close(); 
  }
  else
  {
   arg2.doFilter(arg0, arg1);
  }
 }

 @Override
 public void init(FilterConfig arg0) throws ServletException {
  // TODO Auto-generated method stub
  
 }

}


Again very easy. Just a mere annotation to notify it as a filter. Note that here we implement the Filter interface. The value or the urlPatterns should be available. Using both is illegal as per the specification.

In the coming weeks i will cover the other new annotations available with JEE6 and wrap up with a comprehensive example using them together. If JEE6 will replace Spring framework or not is not a question by itself, but i believe we would be seeing some fierce competition between the two. The annotations vs xml debate is more or less resolved with people with preference for each holding their own grounds. I believe a little bit from both worlds would be beneficial for an application.

You can download and run a sample example which i have uploaded here. If you are using JBoss-AS7 all you need to do is run the application server on standalone mode and do a mvn package jboss-as:deploy and point the browser to http://localhost:{port}/servlet3.0.

That is it for today. Thank you for reading and if you have any comments or suggestions for improvement, please do leave by a comment.

Have a good day all!!

Thursday, December 13, 2012

Configuring syntax highlighting for your blog

Thought i would put up a quick reference guide on how to configure syntax highlighting for people trying to figure it out for the first time. It is not that hard anyways. Let me guide you step by step. First of all just before the close head (</head>) tag insert the following;


<style type='text/css'>
.dp-highlighter
{
 font-family: &quot;Consolas&quot;, &quot;Courier New&quot;, Courier, mono, serif;
 font-size: 12px;
 background-color: #E7E5DC;
 width: 99%;
 overflow: auto;
 margin: 18px 0 18px 0 !important;
 padding-top: 1px; /* adds a little border on top when controls are hidden */
}

/* clear styles */
.dp-highlighter ol,
.dp-highlighter ol li,
.dp-highlighter ol li span 
{
 margin: 0;
 padding: 0;
 border: none;
}

.dp-highlighter a,
.dp-highlighter a:hover
{
 background: none;
 border: none;
 padding: 0;
 margin: 0;
}

.dp-highlighter .bar
{
 padding-left: 45px;
}

.dp-highlighter.collapsed .bar,
.dp-highlighter.nogutter .bar
{
 padding-left: 0px;
}

.dp-highlighter ol
{
 list-style: decimal; /* for ie */
 background-color: #fff;
 margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */
 padding: 0px;
 color: #5C5C5C;
}

.dp-highlighter.nogutter ol,
.dp-highlighter.nogutter ol li
{
 list-style: none !important;
 margin-left: 0px !important;
}

.dp-highlighter ol li,
.dp-highlighter .columns div
{
 list-style: decimal-leading-zero; /* better look for others, override cascade from OL */
 list-style-position: outside !important;
 border-left: 3px solid #6CE26C;
 background-color: #F8F8F8;
 color: #5C5C5C;
 padding: 0 3px 0 10px !important;
 margin: 0 !important;
 line-height: 14px;
}

.dp-highlighter.nogutter ol li,
.dp-highlighter.nogutter .columns div
{
 border: 0;
}

.dp-highlighter .columns
{
 background-color: #F8F8F8;
 color: gray;
 overflow: hidden;
 width: 100%;
}

.dp-highlighter .columns div
{
 padding-bottom: 5px;
}

.dp-highlighter ol li.alt
{
 background-color: #FFF;
 color: inherit;
}

.dp-highlighter ol li span
{
 color: black;
 background-color: inherit;
}

/* Adjust some properties when collapsed */

.dp-highlighter.collapsed ol
{
 margin: 0px;
}

.dp-highlighter.collapsed ol li
{
 display: none;
}

/* Additional modifications when in print-view */

.dp-highlighter.printing
{
 border: none;
}

.dp-highlighter.printing .tools
{
 display: none !important;
}

.dp-highlighter.printing li
{
 display: list-item !important;
}

/* Styles for the tools */

.dp-highlighter .tools
{
 padding: 3px 8px 3px 10px;
 font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif;
 color: silver;
 background-color: #f8f8f8;
 padding-bottom: 10px;
 border-left: 3px solid #6CE26C;
}

.dp-highlighter.nogutter .tools
{
 border-left: 0;
}

.dp-highlighter.collapsed .tools
{
 border-bottom: 0;
}

.dp-highlighter .tools a
{
 font-size: 9px;
 color: #a0a0a0;
 background-color: inherit;
 text-decoration: none;
 margin-right: 10px;
}

.dp-highlighter .tools a:hover
{
 color: red;
 background-color: inherit;
 text-decoration: underline;
}

/* About dialog styles */

.dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; }
.dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; }
.dp-about td { padding: 10px; vertical-align: top; }
.dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; }
.dp-about .title { color: red; background-color: inherit; font-weight: bold; }
.dp-about .para { margin: 0 0 4px 0; }
.dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; }
.dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; }

/* Language specific styles */

.dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; }
.dp-highlighter .string { color: blue; background-color: inherit; }
.dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; }
.dp-highlighter .preprocessor { color: gray; background-color: inherit; }

</style>
<!-- Add-in CSS for syntax highlighting -->  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shCore.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCpp.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCSharp.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCss.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushDelphi.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJava.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJScript.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushPhp.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushPython.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushRuby.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushSql.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushVb.js' type='text/javascript'/>  
<script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushXml.js' type='text/javascript'/>  

Next up you need to initialize a few javascript functions to make the syntax highlighting work. Therefore insert the following snippet just before the close body (</body>) tag;


<!-- Add-in Script for syntax highlighting -->  
<script language='javascript'>  
dp.SyntaxHighlighter.BloggerMode();  
dp.SyntaxHighlighter.HighlightAll(&#39;code&#39;);  
</script> 
That is it. Afterwards whenever you want to post a code in one of your posts just have your code within pre tag blocks as follows;

<pre class="java" name="code">
//your code goes here
</pre>


Note that before pasting code within the block you need use an html encoder. I usually prefer this html encoder which is an online tool. Also there are many options you can use within the class attribute. More information on the brushes available can be found here.

Happy coding people!!

Friday, November 30, 2012

How to start a thread on JBoss startup

I recently had to initiate a thread to read mails on server start-up. This had to run after the application was deployed since the thread class depended on a few classes of the application. Note that we are running on JBoss 4.2.3 currently, so i am not sure how this works with latest versions of JBoss.

You need to create a folder called deploy.last within your deployment directory (e.g : default configuration). Then we first create a normal interface/implementation as follows;


public interface EmailRetrieverInvokerServiceMBean {

 void start() throws Exception;

 void stop();
}



public class EmailRetrieverInvokerService implements
  EmailRetrieverInvokerServiceMBean {

 public void start() throws Exception {

  
  MailRetriever mailRetriever= new MailRetriever();
  mailRetriever.start();
 }

 public void stop() {
  
            MailRetriever.START_STOP_FLAG = true;

 }
}


Just a normal interface and implementation. Note that the start() method will be called when we deploy the application. The MailRetriever class has an implementation as follows;


public class MailRetriever extends Thread {

   public static boolean START_STOP_FLAG = false;

    @Override
    public void run() {
        
        log.info("MailRetriever started....");

        //Until the flag is not set to true, this thread will keep running
        while (!START_STOP_FLAG) {
            try {
                
                
             
             //Do mail reading

             //Then sleep for a specified time until the next iteration
                Thread.sleep(1000 * 60 * mailPollingDelay);
            } catch (Exception ex) {
                log.error("MailRetriever.run()" + ex.getMessage(), ex);
                //Exception handling and thread respawning should be handled
            }
        }
    }
}


This is the thread that will be started when the start() method of our MBean implementation class is invoked. The thread will continue to run until the boolean flag is set to true. Then to wire it up, you need to specify a jboss-service.xml which should go in the META-INF directory when building your distribution. Let us have a look at what that looks like;


<?xml version="1.0" encoding="UTF-8"?>

<server>
   <mbean code="com.service.EmailRetrieverInvokerService"
   name="com.service:service=EmailRetrieverInvokerService">    
  </mbean>
</server>


Within this xml we define the fully qualified path to our interface class that we defined and give a name where we can access our implementation as a normal MBean definition. If you are using a maven build then all you need to do is create this XML file and put it under src/main/resources/META-INF. This will put it under the META-INF during the distribution creation stage.

As a last step what you need to do is bundle everything up as a service archieve (SAR). You can achieve this using maven as follows;


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.example</groupId>
 <artifactId>mailreader</artifactId>
 <packaging>sar</packaging>
 <version>1.0</version>
 <name>Mail Reader</name>

 <build>
 <finalName>MailReader</finalName>
  <plugins>

   <plugin>
    <groupId>net.sf.maven-sar</groupId>
    <artifactId>maven-sar-plugin</artifactId>
    <version>1.0</version>
    <extensions>true</extensions>
   </plugin>
  </plugins>

 </build>


 <properties>
  <project.build.sourceEncoding>UTF-8
  </project.build.sourceEncoding>
 </properties>


</project>


A service archive will be created for you. Then it is just a matter of copying the SAR file onto your deploy.last which you created within the jboss deployment directory. This will guarantee that the thread will run after all other components are deployed within jboss.

That's it. If you have any queries, comments, suggestions, please leave them which is much apprecaited as always.

Thank you for reading and have a great day!!

Monday, November 26, 2012

How cool is integration testing with Spring+Hibernate

I am guilty of not writing integration testing (At least for database related transactions) up until now. So in order to eradicate the guilt i read up on how one can achieve this with minimal effort during the weekend. Came up with a small example depicting how to achieve this with ease using Spring and Hibernate. With integration testing, you can test your DAO(Data access object) layer without ever having to deploy the application. For me this is a huge plus since now i can even test my criteria's, named queries and the sort without having to run the application.

There is a property in hibernate that allows you to specify an sql script to run when the Session factory is initialized. With this, i can now populate tables with data that required by my DAO layer. The property is as follows;


 <prop key="hibernate.hbm2ddl.import_files">import.sql</prop>

According to the hibernate documentation, you can have many comma separated sql scripts.One gotcha here is that you cannot create tables using the script. Because the schema needs to be created first in order for the script to run. Even if you issue a create table statement within the script, this is ignored when executing the script as i saw it.

Let me first show you the DAO class i am going to test;


 package com.unittest.session.example1.dao;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.unittest.session.example1.domain.Employee;

@Transactional(propagation = Propagation.REQUIRED)
public interface EmployeeDAO {

 public Long createEmployee(Employee emp);
 
 public Employee getEmployeeById(Long id);
}



package com.unittest.session.example1.dao.hibernate;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.unittest.session.example1.dao.EmployeeDAO;
import com.unittest.session.example1.domain.Employee;

public class EmployeeHibernateDAOImpl extends HibernateDaoSupport implements
  EmployeeDAO {

 @Override
 public Long createEmployee(Employee emp) {
  getHibernateTemplate().persist(emp);
  return emp.getEmpId();
 }

 public Employee getEmployeeById(Long id) {
  return getHibernateTemplate().get(Employee.class, id);
 }
}

Nothing major, just a simple DAO with two methods where one is to persist and one is to retrieve. For me to test the retrieval method i need to populate the Employee table with some data. This is where the import sql script which was explained before comes into play. The import.sql file is as follows;



 insert into Employee (empId,emp_name) values (1,'Emp test');

This is just a basic script in which i am inserting one record to the employee table. Note again here that the employee table should be created through the hibernate auto create DDL option in order for the sql script to run. More info can be found here. Also the import.sql script in my instance is within the classpath. This is required in order for it to be picked up to be executed when the Session factory is created.

Next up let us see how easy it is to run integration tests with Spring.


 package com.unittest.session.example1.dao.hibernate;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

import com.unittest.session.example1.dao.EmployeeDAO;
import com.unittest.session.example1.domain.Employee;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring-context.xml")
@TransactionConfiguration(defaultRollback=true,transactionManager="transactionManager")
public class EmployeeHibernateDAOImplTest {

 @Autowired
 private EmployeeDAO employeeDAO;
 
 @Test
 public void testGetEmployeeById() {
  Employee emp = employeeDAO.getEmployeeById(1L);
  
  assertNotNull(emp);
 }
 
 @Test
 public void testCreateEmployee()
 {
  Employee emp = new Employee();
  emp.setName("Emp123");
  Long key = employeeDAO.createEmployee(emp);
  
  assertEquals(2L, key.longValue());
 }

}


A few things to note here is that you need to instruct to run the test within a Spring context. We use the SpringJUnit4ClassRunner for this. Also the transction attribute is set to defaultRollback=true. Note that with MySQL, for this to work, your tables must have the InnoDB engine set as the MyISAM engine does not support transactions.

And finally i present the spring configuration which wires everything up;


 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="  
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">


 <context:component-scan base-package="com.unittest.session.example1" />
 <context:annotation-config />

 <tx:annotation-driven />

 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="packagesToScan">
   <list>
    <value>com.unittest.session.example1.**.*</value>
   </list>
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
    <prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/hbmex1</prop>
    <prop key="hibernate.connection.username">root</prop>
    <prop key="hibernate.connection.password">password</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <!-- -->
    <prop key="hibernate.hbm2ddl.auto">create</prop>
    <prop key="hibernate.hbm2ddl.import_files">import.sql</prop>
   </props>
  </property>
 </bean>

 <bean id="empDAO"
  class="com.unittest.session.example1.dao.hibernate.EmployeeHibernateDAOImpl">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

</beans>

That is about it. Personally i would much rather use a more light weight in-memory database such as hsqldb in order to run my integration tests.

Here is the eclipse project for anyone who would like to run the program and try it out.


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!!