Monday, 31 March 2008

Creating Tab Activity in Adnoird

While developing your application, you may need a window that contains tabs, e.g. wizard window or settings window.

Android supports this kind of views, tabs one. Android gives you TabHost, TabWidget and TabSpec classes for building your tabbed activity.

To create your tabbed activity, you will build your layout xml file contains TabHost tag have two elements:

  • TabWidget that will hold the navigation tabs title and icon
  • FrameLayout that will hold LinearLayout for each tab content

Then, in your activity code you will build the tabs content, assign a title and icon for each tab and then add the tabs to your tab host object.

The following are steps for creating activity have two tabs in its view:

  1. Create the activity layout that contains TabHost, TabWidget and two linear layouts inside frame layout for your two tabs:
  2. <LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TabHost android:id="@+id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TabWidget
    android:id="@android:id/tabs"
    android:layout_width="fill_parent"
    android:layout_height="65px" />

    <FrameLayout
    android:id="@android:id/tabcontent"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingTop="70px">

    <LinearLayout
    android:id="@+id/tab1"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    </linearlayout>

    <LinearLayout
    android:id="@+id/tab2"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    </linearlayout>
    </framelayout>
    </tabhost>
    </linearlayout>
  3. Inside your activity onCreate method, you will init the tabs view as following:
    1. Acquire the tab host object and call setup() function for starting the setup
    2. tabs = (TabHost) findViewById(R.id.tabhost);
      tabs.setup();

    3. Create your first tab by building TabSpec object and pass its layout content:
    4. TabSpec tab1 = tabs.newTabSpec("tab1");
      tab1.setContent(R.id.tab1);

    5. Set the tab title and icon:
    6. tab1. setIndicator(“my tab one”, drawable_object);

    7. Then, add this tab to the tab host object
    8. tabs.addTab(tab1);

    9. Repeat steps (2), (3) and (4) for the second tab.
  4. To set current tab, call setCurrentTab method in tab host object with the required tab index
  5. tabs.setCurrentTab(0);

Attached is a complete activity code and layout xml file for two tabs activity.

Monday, 24 March 2008

Rendering Web Pages inside Android Activity

While you create Android activities, you supply the activity view content either through XML or dynamically through the code. But, sometimes the content in the view, specially the static content (content will not change with different runs) may be a web page; e.g. “Help” Activity or “Terms and Conditions” Activity of your application.

These contents can be done as web pages, and that will help you in changing the content without affecting the client side application binary. However, sometimes you need to open those pages inside your application as activity, not through web-browser, e.g. open “Terms and Conditions” web page for the user to accept or reject through button actions.

Android have a great widget for this usage, it is “WebView” component. It accepts either plain text as you use in Text View component or a URL to a web page to render inside your activity.

The following example show a layout for a sample activity contains web view to show eSpace site home page:
  • You first create the layout XML file contains your component as following:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <WebView
    android:id="@+id/myWebView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />

    </LinearLayout>
  • And then supply the URL to the web view through your activity “onCreate” method code:

    WebView webView = (WebView) findViewById(R.id.myWebView);
    webView.loadUrl(“http://www.espace.com.eg”);

  • Now, the given URL is rendered inside the web view widget and you can deal with the opened web page with all functionality available from Android web-kit (scroll, zoom in, zoom out, etc).

Monday, 17 March 2008

Maven Plugins for Manipulating Databases

Some projects have database in their infrastructure, and deploying these projects involves building database schema and initializing some tables with default data.

Using Maven, you can get great help in this point. Maven can help you in building and manipulating your project database through its POM file configuration and in your defined order of execution.

Maven built on plugins. You add plugins configuration into your POM file as your build script needs. Maven has a great set of database manipulation plugins, for example:
  1. Mojo, SQL Maven Plugin

  2. Torque, Maven2-plugin

I recommend the first one for simple usage, Mojo SQL Maven Plugin. It is great and simple plugin for basic database manipulation. You can create your SQL script file(s) and define an execution configuration inside the plugin tag and configure it to run after specific maven lifecycle phase.

You can have more than one execution, everyone have its own lifecycle phase to run after and have its SQL script files set to run against the configured DB.

For example, the next configuration will run after the “package” phase and execute the given SQL script file against the given mysql DB configuration:


<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
</dependency>
</dependencies>
<configuration>
<driver>com.mysql.jdbc.Driver</driver>
<autocommit>true</autocommit>
</configuration>
<executions>
<execution>
<id>deploy-schema-data</id>
<phase>package</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<url>jdbc:mysql://localhost/test-db</url>
<username>root</username>
<password>root</password>
<srcFiles>
<srcFile>
src/main/resources/sql/init-data.sql
</srcFile>
</srcFiles>
</configuration>
</execution>
</executions>
</plugin>

Sunday, 9 March 2008

Java Annotations and Aspect Oriented Programming

Starting from Java5, Java starts a trend of annotation-based development. Java gives you ability to build your custom annotations as required and build your configuration through annotations.

In one of my old projects I created custom transaction manager using custom Java annotations and Aspects. I used AspectJ library together with Spring Framework for creating Aspects that run over custom annotations defined as point-cuts.

Next, we will iterate on how we can create aspects run over custom annotations using AspectJ and Spring Framework. This will be a simple example of creating custom transaction manager for starting, committing and rollback.

  1. To create custom annotation, you will create annotation interface and define its target (METHOD, FIELD, PARAMETER, TYPE, etc). The next one is MyTransaction annotation that will be used to annotate transactional methods.

  2. @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface MyTransaction {
    }

    To use it, just add annotation “@MyTransaction” before any method you want to be handled using your transaction manager:

    @MyTransaction
    Public void doCode(){
    }

  3. Creating aspect using AspectJ and Spring Framework is based also on annotations. You have annotation called “@Aspect” used to annotate classes that will be waved as aspects using AspectJ Weaver. You will have aspect for your Transaction Manager as following :

  4. @Aspect
    public class MyTransactionManager {
    }

  5. This aspect will have point-cuts over your custom annotation. This will be done as following:

  6. @Pointcut("execution(@MyTransaction * *(..))")
    private void myTransactionMethod() {
    //No code needed here, just empty method
    }

    The last method defines point-cut over all methods have annotation “MyTransaction”. You can imagine this point-cut as place holder at specific parts of your code.

  7. After creating your point-cut, you need to create your aspect advice(s). Each advice is just a method that will run at specific point-cut at some time (before, after or around).
    1. The following advice will run at point cut “myTransactionMethod” and before running the method have this point-cut (the methods annotated with “MyTransaction”). As you see from its name it will start new transaction.

    2. @Before("myTransactionMethod()")
      public void doStartTransaction() {
      //code for starting transaction
      }

    3. This advice will run after returning from the point-cut. As you see from its name its code will commit the last opened transaction.

    4. @AfterReturning(pointcut = "myTransactionMethod()")
      public void doCommitTransaction() {
      //code for committing transaction
      }

    5. Well, your transactional method may fail and need to rollback. Then, you will need to have advice run after throwing exception at your point-cut.

    6. @AfterThrowing(pointcut = "myTransactionMethod()")
      public void doRollbackTransaction() {
      //rollback transactional code
      }

The last example is just starting point for you to know how you can use Java Custom Annotations together with Aspect Oriented Programming to create a great concern separated components like the one we do.

I attached the two example classes, MyTransaction.java annotation and MyTransactionManager.java aspect to this post.

Attachment File