Pages

Sunday, June 16, 2013

Android Thread Model

Foreword

Like many other GUI frameworks/toolkits Android also works with single thread model. This if not correctly handled may result in unresponsive applications, and poor user experience, especially when the UI thread performs long running operations. Another challenge is to give the user feedback of on going work.

First aim of this paper will try to explain how this problem should be handled. Second aim is to introduce the user of Thread related “Design Patterns”.

Below code samples are should be treated pseudo codes, close to java, and the use of Threads will be explicitly shown.

Single Thread Model

Android follows the single threaded approach that all other GUI frameworks take. This means all the tasks that GUI needs to perform will be performed by the UI Thread and all the tasks will be performed sequentially. This includes events triggered by the user that may take some time.

Although there are some attempts on designing multi-threaded GUI frameworks/toolkits all merged to single threaded model because of the problems such as deadlocks and race conditions.

Sample 1: Save Operation

An application that uses Android Internal Storage will take only small amount of time to save. However most applications today try to update it’s data to online servers in order to share the data amongst different devices. The operations that must be performed on the web would take many times more than the previous case.

 btnSave.setOnClickListener(new OnClickListener() {   
   @Override public void onClick(View v) {   
    saveInternalStorage();   
    synchronizeOnWeb(); // long running operation,   
   }  
 });  

Above code piece shows a save button blocking the UI until the operation performed on the web ends. 

Sample 2: Running The Save On A Background Thread

With the use of the Java Thread api we can schedule our long running operations on another thread and allow the user continue his/her work on the UI. 

 btnSave.setOnClickListener(new OnClickListener() {   
   @Override public void onClick(View v) {  
    new Thread(new Runnable() {   
      @Override public void run() {   
       longRunningOperation(); } }).start();   
      }  
    }  
 );  

Sample 3: Giving Feedback to User

When there is a background process running such as the one on the previous example we should inform the progress to user. Following example animates the save button to inform the progress. Here is how the animation will be performed step by step:

In order to realize this we will have to change the save buttons image from an background thread:

 public void onClick(View v) {  
   new Thread(new Runnable() {  
    public void run() {  
 ...  
      btnSave.setImageResource(R.drawable.progress1);  
 ...  
    }  
   }).start();  

But the above code results with the following exception:

 android.view.ViewRootImpl$CalledFromWrongThreadException:  
   Only the original thread that created a view hierarchy can touch its views.  
   at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)  
 ...  
   at android.widget.ImageView.setImageResource(ImageView.java:352)  
   at mca.activities.NoteListActivity$3$1.run(NoteListActivity.java:69)  
   at java.lang.Thread.run(Thread.java:856)  

This exception message simply tells us that access to an object controlled by the UI Thread such as view objects, have to be done in with certain patterns so that thread-safety does not breake.

Scheduling Tasks For The UI Thread

Android API gives us three main options to schedule tasks to be run on the UI thread:
  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • AsyncTask

Activity.runOnUiThread and View.post

Activity.runOnUiThread ve View.post metotları birbirine oldukça yakındır. Farkları biri Activity objesi üstünde tanımlıdır diğeri view objesi üstünde, runOnUiThread eğer aktif thread zaten UI Thread ise işi anında çalıştırırken view.post işi her halükarda planlamaktadır.

These two methods are quite similar. They only have trivial differences. One is defined on an Activity object other is defined on any View object. runOnUIThread runs the callback code immediately if the runOnUIThread method is called on the UI Thread. The latter one schedules by default.

Thus, we rewrite the above code:

1. With Activity.runOnUiThread(Runnable):

 public void onClick(View v) {  
  new Thread(new Runnable() {  
  public void run() {  
   MyActivity.this.runOnUiThread(new Runnable() {  
   @Override  
   public void run() {  
    btnTest.setImageResource(R.drawable.progress1);  
   }  
   });  
  }  
  }).start();  
 }  

2. With View.post(Runnable):

 public void onClick(View v) {  
  new Thread(new Runnable() {  
  public void run() {  
   myBtn.post(new Runnable() {  
   @Override  
   public void run() {  
    myBtn.setImageResource(R.drawable.progress1);  
   }  
   });  
  }  
  }).start();  
 }  

Since now we know how to schedule commands for the UI thread we could write code that will change the save button into a progress indicator.

 final ProgressControllerAnimationThread progressT =  
 new ProgressControllerAnimationThread(btnSave, R.drawable.save);  
 progressT.start();  
 new Thread(new Runnable() {  
   @Override  
   public void run() {  
     longRunningOperation();  
     progressT.end(true);  
   }  
 }).start();  

Progress animation is controlled by the ProgressControllerAnimationThread class which extends the Thread class. With the and of the worker thread this thread is signaled via the end method with parameter true or false indicating success or failure. This aproach decouples the part that does the work and the one that controls the animation.

AsyncTask

Android api’ı arka plan işler için AsyncTask  nesnesini sunmaktadır. Kendi threadlerimizi oluşturmak yerine uygun durumlarda bu sınıfta kullanılabilir. AsyncTask template tasarım örüntüsü ile tasarlanmış soyut bir sınıftır. Params, Progress, Result isimli üç generic tanımlar. AsyncTask oluşturulduktan sonra execute method’u ile task başlatılır.
AsyncTask kullanıcının türetebileceği dört metot sunar:

Another option is to extend from the AsyncTask abstract class. It follows the template method pattern. Needs three generics to be defined Params, Progress, Result.

Pattern provides us the following methods to override:

onPreExecute
Intended to do the necessary setup on the UI Thread.

doInBackground(Params...)
Must be implemented. Works in a background thread. Our long running operation should be defined here. In order to send progress message to UI Thread publishProgress method should be used.

onProgressUpdate(Progress...)
Run on the UI Thread. Run as the progress is reported by calls to the publishProgress method.

onPostExecute(Result)
A breakdown method. Runs on the UI Thread.

Plus there is the execute method which starts up the task.

Solution to problem defined above will be similar to this with the AsyncTask class:

 public void onClick(View v) {  
  AsyncTask testTask = new AsyncTask...{  
    protected Void doInBackground(Void... params) {  
 ...  
      while (System.currentTimeMillis() - start < 2000) {  
        doApartOfLongRunningOp();  
        if (System.currentTimeMillis() - changeTime > 100) {  
         changeTime = System.currentTimeMillis();  
         publishProgress(progress++);  
        }  
      }  
     return null;  
    }  
    protected void onProgressUpdate(Integer... values) {...}  
  };  
  testTask.execute();  
}  

Note that this solution is much more coupled than the previous one.

Handler and Looper Pattern

Although useful threads are costly; so we must be sure that threads our application create are not many and they get to end. Handler & Looper pattern helps us with that. It allows us to create a thread which will be used to handle background tasks removing the need to instantiate a new thread every time. Basic usage pattern:

  class BackgroundThread extends Thread {  
    public Handler handler;  
    public void run() {  
      Looper.prepare();  
      handler = new Handler() {  
        public void handleMessage(Message msg) {  
          // process incoming messages here  
        }  
      };  
      Looper.loop();  
    }  
  }  

Looper.loop will associate the running thread as a ‘looper’. So make sure that it’s on the run method of the new thread. Handler object will associate itself with the looper. Looper.loop will cause the thread to keep running and handle messages until Looper.quit is called. Through the handler object this thread will execute the messages, events send to it’s queue. Handler.sendMessage or Handler.post maybe used to schedule  messages and events.

UI thread has a predefined looper. So a new handler defined on the UI thread may be used as a new queue that holds messages to UI thread. Trying to create a handler without the looper will cause an exception.

Thread Priorities

By default background threads have much less priorities then than the UI thread. If it’s required that your thread has more CPU time you should give it a higher priority with Thread.setPriority method.

Last Words

Like many other Android GUI is designed with single threaded model. For better user experience we must learn how we should design an multithreaded applications with the API.

Resources


  • API Guide: “Processes and Threads”, http://developer.android.com/guide/components/processes-and-threads.html
  • “Concurrency In Action”, Brian Goetz

Tuesday, May 7, 2013

Top Dow Approach to Automated User Interface Testing for Web Applications


This is something I wrote more than a year ago. Although I have not worked much on web UI testing for some time I believe points it makes are still valid.

Abstract

Here I try to address the problems in automating web user interface tests as a part of continuous integration process and propose some improvements to lower the cost of automated UI tests.

I suggest a top down approach where web user interface testing will be written with minimal consideration of html elements but with more focus on business requirements.

Basics

Test coverage is one of the most important indicator of good quality software. An enterprise software typically must have the unit, integration, acceptance and stress tests. However writing and maintaining good quality tests has it’s costs as well as it’s benefits.

Unit Tests

Unit tests typically test  the most basic, independent function blocks of the application. They run typically fast. A good functioning unit test must fail when the function it tests changes behaviour.
There are a good number of tools for unit testing which helps the development and maintenance like the JUnit, NUnit. Also modern IDE’s support running of these tests without much effort.

Integration Tests 

Integration tests, test how the dependent blocks of the application work together. Most modern enterprise applications are designed using more than one often complex frameworks and libraries. Integration test typically run longer than unit tests and more costly than unit tests. Often mock objects are created to be able to test certain parts of the application.

Acceptance Tests

Acceptance tests, are aimed to test directly on the final product and it’s often the most complex and costly to maintain. Different products for both desktop and web testing is available. java.awt.Robot, Watir and Selenium are examples.

Stress Tests

Stress tests, are aimed to make sure the final product meets the non-functional requirements. Non functional requirements of the applications are just as important as the functional if not more. Producing load and making sure the system performs well under load is especially important.

Web Acceptance Tests And Reducing It’s Costs

Directly testing a web application is quite challenging. Most basic approach to acceptance testing may be considered “bottom up” trying to fulfill the business cases by thinking in terms of the basic html elements. Typical problems with this approach are:

Bottom Up Approaches to Web Acceptance Tests

Referencing the web elements 

Referencing the elements is required in order to perform functions, clicking, entering text and such, directly from the browser. Although lots of alternatives exists to select elements, referencing id’s, certain text or xpath queries, they are cumbersome and hard to maintain. XPath approach is further harder to understand.

Non Data Centric 

Most of the test frameworks don’t come with basic data populators needed. So most tests are run with specific data against an empty databases or they have to be cleaned up.

Easing the Bottom Up Approach

To overcome the cumbersomeness of writing acceptance tests tools such as Watir and Selenium, have recorder software which would record the users browser actions and produce scripts. Although this eases the initial creation of the test scripts does not resolve the maintenance and data population issues.

Top Down Approach 

Web tests should be thought of what might be called “top down” approach. Which is minimal thinking of html elements more on business requirements and if they are met.

Most web application are made of forms and applications mostly performs by filling and submitting these forms.

Minimal amount of referencing the elements should be made through the test page preferably just for the forms which would be filled and submitted.

Most of the user data required to fill out forms could be filled out using either guessing, based on id’s, or elements neighbour labels, or through extra invisible information to the user. These extra information could be easily integrated with modern component based  web frameworks. Also they could easily be switched on for testing and off for production use.

This approach would remove the burden of maintaining change of id’s and places of html elements.

Meta-Data Required for Finding and Filling Html Input Elements

Typical meta-data for an html element would be related with identifying it and what kind of data it will be required to fill it. For a name field meta-data would be, an type id, an actual html id allowing the system to find it, it’s validation requirements like, if it’s required and what it’s max length is.

Recognizing the Errors

Every enterprise application has standard way’s to inform the users of errors through html elements.

System must be able to recognize errors. Both for testing if validations work and trying out new values where needed.

Integrating the Meta-Data System

This meta-data required by top-down approach could be integrated in component based, declarative web frameworks.

A typical JSF, standard user interface framework for Java, component holds nearly all the information required by the system;
 <tow:inputtext id="name" value="#{new.name}" label="#{lbl.name}"
 required="true" maxLength="30" />  

An extra information could be added for determining the components type id.

Component meta-data required could be either generated as invisible html elements embedded in the page. Or source code could be supplied for the test executor which would parse the source and extract the meta-data it requires.

Code Samples for Both Approaches

Bottom Up Script

    browser = Watir::Browser.start "http://localhost:8181/petclinic/"
    browser.link(:text, "Find owner").click
    browser.link(:text, "Add Owner").click
    browser.button(:value, "Add Owner").click
    if !browser.text.include?("is required ")
      puts "required validation failed"
    end
    browser.text_field(:id, "telephone").set("asdf")
    browser.button(:value, "Add Owner").click
    if !browser.text.include?("must be all numeric ")
      puts "numeric validation failed"
    end
    browser.text_field(:id, "firstName").set("Ortega")
    browser.text_field(:id, "lastName").set("Junior")
    browser.text_field(:id, "address").set("Argentina")
    browser.text_field(:id, "city").set("Buenos Aries")
    browser.text_field(:id, "telephone").set("999")
    browser.button(:value, "Add Owner").click
    if !browser.text.include?("Owner Information")
      puts "Failed to create Owner"
    end

Top Down Script

    tow = TOW.new
    tow.goto 'http://localhost:8181/petclinic/'
    tow.click "Find owner"
    tow.click "Add Owner"
    tow.testForm FormSpec.new({:id => "owner", :allRequired => true})
    tow.assertNoErrors

Both scripts are for creating an owner on a petclinic application. Petclinic application is a enterprise example application freely available over the web.

Bottom up script is generated mostly as it’s using TestWise recorder. The script as it’s, is highly coupled. Change in any one of the 9 access selectors, firstName, lastName and such, will cause the script to fail. Furthermore running the script twice could cause the uniqueness constraints of the db fail.

Top down script uses a sample framework, which is much less coupled with both the data and html elements. It only address 3 html elements. Further it could be run without the fear of running into data uniqueness issues since it uses data dictionaries to populate the data. It also does test both the required and numeric validations.

Thursday, January 31, 2013

After the Management 3.0 Event

I had the chance to join the Management 3.0 by Jurgen Appelo event organized by Scrum Turkey. Thanks to Barış Bal, for organizing such a rare event in Ankara, my company, Innova, for sending me there and old friend Mert Çalışkan for sharing the event photos.

What is it about?
For me It was about the agile approach to management with focus on the people. Not just getting things done and profiting  but also while getting things done, making the people who do the work happy and proud.

What did I learn?

  • I should read about the "Delivering Happiness" model of Zappos.
  • Sharing the bonuses? You must learn how the ING, Second Life shares the bonuses. Jurgen has an article on this called "Merit Money". Join his mail list to read.
  • Lots of people complain about the 360 evaluations but doing the exercises showed me that it's not actually that bad. Maybe the problem is how you implement it.
  • Whatever you do get feedback and get it as soon as possible. Make things in iterations.
  • "Fight complexity with complexity" this could be my new motto working for corporate's where there is a lot of  bureaucracy. 
  • I knew that marketing is important but now I realize that I should be thinking on It a lot more than I currently do. Would you call your book Management 3.0 especially if it does not have a predecessor?
  • This is something that I actually got from the people I met. People doing Scrum have generally hard time to tell the customer to wait for the next sprint. Some suggested that KANBAN could be actually better which got me motivated to reading more on it.
  • How much effect the word "urgent" has effect.
  • Intrinsic motivators: I guess I am a curious person :)
  • Lots of good reads. I already started with the "How to change the world".

More thanks to
People who shared the table with me for the 2 days :)
our happy team

Friday, January 25, 2013

HTML5 Presentation

I had a fun time with Ankara JUG guys, my presentation:
And an example web game app. that I plan to write more about later: https://github.com/mcalpay/geoshooter