FinanTrak iPhone version is now available for download.

http://itunes.apple.com/us/app/finantrak/id491256295?mt=8&ign-mpt=uo%3D2


I’ve developed a personal finance tracking application named FinanTrak. Its features include:

* Multiple accounts, 4 account types
* Charts, monthly budget, transactions verification
* Backup and restore, export to CSV
* Password protection

Both full and free versions are available in the Android Market.


Our paper “A 2D Barcode Validation System for Mobile Commerce” got accepted and will be published in IJHCR http://www.igi-global.com/ijhcr/


My first paper “A 2D Barcode Validation System for Mobile Commerce” has been published in the GPC 2010 conference proceedings.

More info on the GPC2010 conference: http://gpc2010.ndhu.edu.tw/

My paper: http://www.springerlink.com/content/m0367v103xmt2273/


Android has a built-in testing framework that includes a subset of JUnit.  All of its test-case classes are directly or indirectly derived from JUnit’s TestCase.  If you’re already familiar with JUnit, it’s not that difficult to use the Android Testing Framework.  The Android SDK has some sample testing programs in android-sdk-mac_x86-1.5_r1/platforms/android-1.5/samples/ApiDemos/tests.  Here are some common testing classes in the framework:

TestCase – Plain old JUnit test case.  It can be extended to test utility classes that are not tied to the Android framework.

AndroidTestCase – It extends JUnit’s TestCase.  It’s a lighter testing class compared to ActivityTestCase.  It doesn’t need to launch an activity to run it.  Its getContext() method allows you to get an injected context if you need one.  Since you can get a context from this class, you can inflate your UI objects to test their behaviors.  However, the UI behaviors will not show in the emulator.  I like to use this class to test my data access objects.

ActivityInstrumentationTestCase2<T extends android.app.Activity> – It’s the newer version of ActivityInstrumentationTestCase.  ActivityInstrumentationTestCase is deprecated in Android SDK 1.5.  It’s a heavier testing class compared to AndroidTestCase.  It provides UI and functional testing for a single activity.  You can get an injected activity that you are testing on by calling its getActivity() method.  The activity being tested is launched and finished before and after each test.  Since the activity is launched for each test, you can see how the UI is being tested in the emulator.

ActivityUnitTestCase<T extends android.app.Activity> – It gives the tested activity an isolated environment.  When using it to test an activity, the activity is not attached to the system.  This gives you more control over what kind of environment that you want your activity to be tested in.

ApplicationTestCase<T extends android.app.Application> – It provides testing for Application classes.  It can be used to test the life cycle of an application.

InstrumentationTestRunner – The runner that runs the Android test cases.

The class diagram of those classes probably looks something like this (NOTE: Not all the attributes and operations are listed):

testing-framework

Here is how to create a sample testing project in Eclipse to test the NotesDdAdapter object of Notepad3 (Android’s Notepad tutorial).

  1. Create the Notepad3 project in Eclipse.
  2. Create an Android project in Eclipse called Notepad3Tests.  Make sure the Create Activity option is unchecked.
  3. Make sure Notepad3’s bin folder is included in the build path of Notepad3Tests.
  4. Add this class to the Notepad3Tests project.  It’s the sample code that tests NotesDbAdapter’s createNote(…) function.
  5. public class NotesDbAdapterTests extends AndroidTestCase {
    
        private static final String TAG = "NotesDbAdapterTests";
        private NotesDbAdapter dbAdapter;
    
        @Override
        protected void setUp() throws Exception {
            super.setUp();
    
            // Do some initial setup here
            Log.d(TAG, "In setUp");
            dbAdapter = new NotesDbAdapter(this.getContext());
            dbAdapter.open();
        }
    
        @Override
        protected void tearDown() throws Exception {
            super.tearDown();
    
            // Do some clean up here
            Log.d(TAG, "In tearDown");
            dbAdapter.close();
        }
    
        // Test createNote
        public void testCreateNote() {
    
            long id = dbAdapter.createNote("this is title", "this is body");
            Log.d(TAG, "Note id: " + id);
            assertTrue("Failed to insert note", id > 0);
        }
    }
  6. Modify the AndroidManifest.xml file in the Notepad3Tests project.  a) Click the Application tab.  Under the Application Nodes, add a Uses Library node.  b) Click the node that you just created.  In the Name field on the right, add android.test.runner.  I don’t know why this has to be done since there is not much information about android.test.runner.  c) Click the Instrumentation tab and add an instrumentation.  d) On the right side, in the Name field, add android.test.InstrumentationTestRunner.  In the Target Package field, add com.android.demo.notepad3.
  7. Run Notepad3 so it can be installed on the emulator.
  8. Run NotesDbAdapterTests by selecting Run As > Android JUnit Test.

For more information, please refer to the files in android-sdk-mac_x86-1.5_r1/platforms/android-1.5/samples/ApiDemos/tests.


YaMovies

21May09

YaMoviesI made a small Android program, YaMovies, that parses the RSS feed of weekend box office from Yahoo Movies. It uses two threads to load the movie data and images. The first thread parses the XML file retrieved from http://rss.ent.yahoo.com/movies/thisweek.xml and creates an array of movie objects. In the XML file, each movie has an URL to its image. The URL is parsed and stored in the movie object. The second thread iterates through the movie array and loads the images from their URLs.

The Android SDK has Apache HTTPComponents for you to make HTTP requests and process HTTP responses. For example, to make an HTTP GET request to the RSS feed:

HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://rss.ent.yahoo.com/movies/thisweek.xml");
ResponseHandler responseHandler = new BasicResponseHandler();
String responseBody = client.execute(httpGet, responseHandler);

The responseBody contains the weekend box office information in the XML format. Now it needs to be parsed to extract the information. Fortunately, Android includes SAX and provides an XML parser called Xml. It makes the parsing easy.

Xml xml = new Xml();
MovieSaxHandler movieSaxHandler = new MovieSaxHandler();
xml.parse(responseBody, movieSaxHandler);

The only thing that’s needed is a SAX handler. MovieSaxHandler, extended from SAX’s DefaultHandler, was created to capture the parsed data and create movie objects. When creating a SAX handler, most likely you would override its characters(…) method to get the content of an XML element. However, when the method is called by the parser, make no assumption that all the content will be passed in at once since the parser might consume the content in chunks.

You can download the source code from here.


I recently found a small problem with Axis2 when I was building a POJO service with the code-first approach. I started off with the service’s interface and then generated its WSDL file using Axis2’s Java2WSDL tool. In the generated WSDL file, I noticed that the parameter names of each service were not generated correctly. For example, let’s say you have the following service in your Java interface:

public interface Service {
    public void updateName(int id, String name);
}

The generated WSDL file:

<xs:element name="updateName">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="param0" type="xs:int"/>
            <xs:element minOccurs="0" name="param1" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

The parameter name “id” is replaced with “param0” and the parameter name “name” is replaced with “param1”. This makes your service hard to understand for whoever wants to use it.

However, if you create a POJO service without separating its interface and implementation, the parameter names are generated correctly in the WSDL file. For example:

public class ServiceWithImpl {
    public void updateName(int id, String name) {
        /*
         * Do something there.
         */
    }
}

The generated WSDL file of ServiceWithImpl:

<xs:element name="updateName">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="id" type="xs:int"/>
            <xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

This solves the problem but makes the code inflexible.

I’m using Axis2 1.4.1. If you know any other way to get around it, making Axis2 generate the correct parameter names by giving an interface, please let me know. Thanks.


Android provides Handler and Looper for threads to communication with each other. For example, a child thread is launched to create an image from the web. After it is done, it notifies the main thread (or the UI thread) by sending a message using the handler that’s bound to the main thread’s message queue. The data produced by the child thread can also be included in the message. I often use this pattern if I want the main thread to update the UI with the data produced by the child thread (you probably already know why if you have been playing with threads in Android).

When a Handler is created, it’s bound to the message queue of the thread that created it. If you create it in the main thread, you don’t need any extra code to loop the message queue for the main thread since it’s already been started when you run your application. However, if you are creating a Handler in a child thread, you need to initialize the thread to listen to its message queue before creating the Handler.

For example:

class ChildThread extends Thread {

    public void run() {

        /*
         * You have to prepare the looper before creating the handler.
         */
        Looper.prepare();

        /*
         * Create the child handler on the child thread so it is bound to the
         * child thread's message queue.
         */
        mChildHandler = new Handler() {

            public void handleMessage(Message msg) {

                /*
                 * Do some expensive operations there.
                 */
            }
        };

        /*
         * Start looping the message queue of this thread.
         */
        Looper.loop();
    }
}

Whenever the Handler receives a message, it would run the handleMessage(…). You can do some expensive operations in there. For example, you need to constantly send some data to the server. It probably would be more efficient if you have a thread listening for the messages to do the job instead of creating and running a new thread each time you need to do so.

If you are done with the looper, don’t forget to stop it by using its quit() method. For example:

mChildHandler.getLooper().quit();

Here is an example of creating a two-way communication between the main thread and a child thread:

package sample.thread.messaging;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

/**
 * @author davidkuo
 *
 */
public class ThreadMessaging extends Activity {

    private static final String TAG = "ThreadMessaging";
    private TextView mTextView;
    private Handler mMainHandler, mChildHandler;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mTextView = (TextView)findViewById(R.id.text);

        /*
         * Create the main handler on the main thread so it is bound to the main
         * thread's message queue.
         */
        mMainHandler = new Handler() {

            public void handleMessage(Message msg) {

                Log.i(TAG, "Got an incoming message from the child thread - "  + (String)msg.obj);

                /*
                 * Handle the message coming from the child thread.
                 */
                mTextView.setText(mTextView.getText() + (String)msg.obj + "\n");
            }
        };

        /*
         * Start the child thread.
         */
        new ChildThread().start();

        Log.i(TAG, "Main handler is bound to - " + mMainHandler.getLooper().getThread().getName());

        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                /*
                 * We cannot guarantee that the mChildHandler is created
                 * in the child thread by the time the user clicks the button.
                 */
                if (mChildHandler != null) {

                    /*
                     * Send a message to the child thread.
                     */
                    Message msg = mChildHandler.obtainMessage();
                    msg.obj = mMainHandler.getLooper().getThread().getName() + " says Hello";
                    mChildHandler.sendMessage(msg);
                    Log.i(TAG, "Send a message to the child thread - " + (String)msg.obj);
                }
            }
        });
    }

    @Override
    protected void onDestroy() {

        Log.i(TAG, "Stop looping the child thread's message queue");

        /*
         * Remember to stop the looper
         */
        mChildHandler.getLooper().quit();

        super.onDestroy();
    }

    class ChildThread extends Thread {

        private static final String INNER_TAG = "ChildThread";

        public void run() {

            this.setName("child");

            /*
             * You have to prepare the looper before creating the handler.
             */
            Looper.prepare();

            /*
             * Create the child handler on the child thread so it is bound to the
             * child thread's message queue.
             */
            mChildHandler = new Handler() {

                public void handleMessage(Message msg) {

                    Log.i(INNER_TAG, "Got an incoming message from the main thread - " + (String)msg.obj);

                    /*
                     * Do some expensive operation there. For example, you need
                     * to constantly send some data to the server.
                     */
                    try {

                        /*
                         * Mocking an expensive operation. It takes 100 ms to
                         * complete.
                         */
                        sleep(100);

                        /*
                         * Send the processing result back to the main thread.
                         */
                        Message toMain = mMainHandler.obtainMessage();
                        toMain.obj = "This is " + this.getLooper().getThread().getName() +
                            ".  Did you send me \"" + (String)msg.obj + "\"?";
                        mMainHandler.sendMessage(toMain);
                        Log.i(INNER_TAG, "Send a message to the main thread - " + (String)toMain.obj);

                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };

            Log.i(INNER_TAG, "Child handler is bound to - " + mChildHandler.getLooper().getThread().getName());

            /*
             * Start looping the message queue of this thread.
             */
            Looper.loop();
        }
    }
}

You can download the complete Eclipse project from here.