In this edition of the ADF Mobile blog we'll tackle part 3 of our Web Service examples. In this posting we'll take a look at firing the web service asynchronously and then filling in the UI when it completes. This can be useful when you have data on the device in a local store and want to show that to the user while the application uses lazy loading from a web service to load more data.
Getting the sample code:
Just click here to download a zip of the entire project. You can unzip it and load it into JDeveloper and deploy it either to iOS or Android. Please follow the previous blog posts if you need help getting JDeveloper or ADF Mobile installed. Note: This is a different workspace than WS-Part2
What's different?
In this example, when you click the Search button on the Forecast By Zip option, now it takes you directly to the results page, which is initially blank. When the web service returns a second or two later the data pops into the UI. If you go back to the search page and hit Search it will again clear the results and invoke the web service asynchronously. This isn't really that useful for this particular example but it shows an important technique that can be used for other use cases.
How it was done
1) First we created a new class, ForecastWorker, that implements the Runnable interface. This is used as our worker class that we create an instance of and pass to a new thread that we create when the Search button is pressed inside the retrieveForecast actionListener handler. Once the thread is started, the retrieveForecast returns immediately.
2) The rest of the code that we had previously in the retrieveForecast method has now been moved to the retrieveForecastAsync. Note that we've also added synchronized specifiers on both these methods so they are protected from re-entrancy.
3) The run method of the ForecastWorker class then calls the retrieveForecastAsync method. This executes the web service code that we had previously, but now on a separate thread so the UI is not locked. If we had already shown data on the screen it would have appeared before this was invoked. Note that you do not see a loading indicator either because this is on a separate thread and nothing is blocked.
4) The last but very important aspect of this method is that once we update data in the collections from the data we retrieve from the web service, we call AdfmfJavaUtilities.flushDataChangeEvents(). We need this because as data is updated in the background thread, those data change events are not propagated to the main thread until you explicitly flush them. As soon as you do this, the UI will get updated if any changes have been queued.
Summary of Fundamental Changes In This Application
The most fundamental change is that we are invoking and handling our web services in a background thread and updating the UI when the data returns. This allows an application to provide a better user experience in many cases because data that is already available locally is displayed while lengthy queries or web service calls can be done in the background and the UI updated when they return. There are many different use cases for background threads and this is just one example of optimizing the user experience and generating a better mobile application.