This is an old revision of the document!
When an application is launched, the system creates a process for it (or more, if it declares services in separate processes) and a main thread (UI thread). As discussed in the previous labs, any code you write in your components (unless they are Intent Services) is run on the main thread. But an app might need to perform processing in worker threads, for example, in case of networking or database operations. If we block the UI thread while performing computational intensive code or waiting for certain events, the system will display an ANR (Application Not Responding) dialog.
For working with threads and scheduling tasks we can leverage language-specific APIs for threading, Android specific components or many third-party libraries.
Calling methods from the Android UI API must be done on the UI thread. For example, if you want to show a toast from a worker-thread, use runOnUiThread.
In Android we can create new threads by creating objects of type Thread and Runnable, as we do in Java programming. Since we also need communication with the Android's UI components, the SDK offers a specific type of objects: Handler.
In the following example we load data from db on a different thread:
Runnable runnable = new Runnable() { @Override public void run() { loadData(); } }; Thread thread = new Thread(runnable); thread.start(); }
What happens if we want to show a Toast from the run() method?
public void run() { List<Records> records = loadData(); Toast.makeText(MainActivity.this, records.get(0).getName(), Toast.LENGTH_SHORT).show(); }
We have to use runOnUIThread
public void run() { List<Records> records = loadData(); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, records.get(0).getName(), Toast.LENGTH_SHORT).show(); } }); }
Using the Handler's postDelayed method we can schedule runnables to be executed in the future, on that thread. In this way we can also implement timers in Android.
In the following example we save data to db every [interval] time:
HandlerThread thread = new HandlerThread("I handle things"); thread.start(); writeHandler = new Handler(thread.getLooper()); writeHandler.postDelayed(new Runnable() { @Override public void run() { try { saveDataToDB(); } finally { writeHandler.postDelayed(this, interval); } } }, interval);