MEIC/MERC 2015/2016

Mobile and Ubiquitous Computing

Lab Guide 3

Multithreading and Storage in Android

 


Objectives:

Material:


Exercise I – Threads and Concurrency

The goal of this exercise is introduce you to the behavior of UI thread, worker threads, and AsyncTasks.

1. Basic threading

a) Create an Android application with a single activity and a time ticker thread running in background. The worker thread maintains an internal counter which is incremented every second. For each iteration, the counter value must be printed in the LogCat debugging console. Add two buttons to the main activity: "Start" and "Stop". The "Start" button must reset the counter and start counting. The "Stop" button must stop counting. Tips:

b) Inspect the threads of your application using the debugger. Run the app on the emulator, press the "Start" button, and open the Android Device Monitor (ADM). On the "Devices" panel of ADM (to the left hand side), select your application ID, and click the icon "Update threads" in the top of the panel. Identify the main thread and the worker thread running. Then press the "Stop" button. What happened to the threads?

2. Message passing between threads

a) Import the project SimpleImageDownload.tgz into Android Studio. Compile it, test it on the emulator, and study its code. What does this application do?

b) Modify this application so that the status messages currently printed in the LogCat console are written instead in the UI (below the "Download File" button). Use a handler to enable the worker thread to communicate with the UI thread. Follow the steps described next and explain what this code does:

3. Async tasks

Modify the project SimpleImageDownload in order to download the image using an AsyncTask and show the downloaded image on an ImageView widget. To show the downloaded image in the ImageView, use the method setImageBitmap(). Create an AsyncTask as shown in the reference manual and override method onPostExecute() to update the image view. Tip: Use the following skeleton for your AsyncTask:

public class DownloadTask extends AsyncTask {

    public DownloadTask(ImageView imageView, TextView statusText) {
      ...
    }

    @Override
    protected void onPreExecute() {
      ...
    }

    @Override
    protected Bitmap doInBackground(String... inputUrls) {
      ...
    }

    @Override
    protected void onPostExecute(Bitmap result) {
      ...
    }
}

4. Custom message loops

Learn more about message queues and communication between threads by studying a simple implementation of the classic producers-consumers problem. Import the project ProducerConsumerWithLooper.tgz into Android Studio. Compile it, execute it, and understand its code. Interpret the output of the program in the LogCat console. In the source code, what's the role of the handler variable? What's a Looper?

Exercise II – Local Data Storage

1. Reading and writing files

Download and import the project FileExplorer.tgz into Android Studio. Build the project and run it on the emulator. This application will help you to understand how to read and write files in both internal and external local storage.

a) Launch the application and press the button "Use Internal Storage". Write some text and hit "Write". Then, tap the "Read" button. To make sure that the text is stored persistently, terminate and restart the application. Next, in the main activity, select the same option as before and tap the "Read" button. You should see your text. Explain how the application is performing the read and write file operations by studying the source code of the application. What is the name of the data file accessed by the application?

b) Locate the data file in the file system of the emulator using the adb tool. Proceed as follows:

c) Repeat both these questions for external storage. In the main activity select instead the option "Use External Storage". Note that if you are using an emulator for this example you'll have to make sure that you created an SD card for the instance you're working with. Use the adb to locate the file in the SD card. The path is /sdcard/Android/data/<package>/files.

d) In our file-handling example activities you may notice a subtle potential problem. We're performing I/O operations from the main UI thread. This is almost never a good idea. Reading and writing data to and from filesystem, internal or external, can block the main UI thread. Fix this problem by performing I/O this from a Thread or an AsyncTask.

2. Shared preferences files and SQLite databases

Investigate two additional Android storage mechanisms – shared preferences files and SQLite databases – by reading "Using Shared Preferences" and "Using Databases" from the official Android documentation.