Recipe Updating a Layout from a Separate Thread

As discussed in Chapter 3,"Threads, Services, Receivers, and Alerts," when a time-consuming activity is being run, care must be taken to ensure the UI thread stays responsive. This is done by creating a separate thread for the time-consuming task and letting the UI thread continue at high priority. If the separate thread subsequently needs to update the UI, a handler can be used to post updates to the UI thread.

This recipe uses a button to trigger a time-consuming computation in two parts and updates to the screen when each part is done. The layout, represented by the XML in Listing 4.5, consists of status text called computation_status and a trigger button called action. It utilizes the strings defined in strings.xml, as shown in Listing 4.6.

Listing 4.5 res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/computation_status" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:textSize="36sp" android:textColor="#000" /> <Button android:text="@string/action" android:id="@+id/action" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>

Listing 4.6 res/layout/strings.xml

<?xml version="1.0" encoding="utf-8"?> <resources>

<string name="hello">Hello World, HandlerUpdateUi!</string> <string name="app_name">HandlerUpdateUi</string> <string name="action">Press to Start</string> <string name="start">Starting...</string> <string name="first">First Done</string> <string name="second">Second Done</string> </resources>

The steps to update the UI from a background thread are

1. Initialize a handle to the UI object that updates by the background thread. (Here, it is called av.)

2. Define a runnable function (here, it is called mUpdateResults) that updates the UI as needed.

3. Declare a handler to handle the messages between threads. (Here, it is called mHandler.)

4. In the background thread, set flags as appropriate to communicate the change in status. (Here, the text_string and background_color are to be changed.)

5. In the background thread, have the handler post the UI update function to the main thread.

The activity with these steps is shown in Listing 4.7.

Listing 4.7 src/com/cookbook/handler_ui/HandlerUpdateUi.java package com.cookbook.handler_ui;

import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.os.Handler;

import android.view.View; import android.widget.Button; import android.widget.TextView;

public class HandlerUpdateUi extends Activity { TextView av; //UI reference int text_string = R.string.start; int background_color = Color.DKGRAY;

final Handler mHandler = new Handler(); // Create runnable for posting results to the UI thread final Runnable mUpdateResults = new Runnable() { public void run() {

av.setText(text_string);

av.setBackgroundColor(background_color);

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);

av = (TextView) findViewById(R.id.computation_status);

Button actionButton = (Button) findViewById(R.id.action); actionButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) { do_work();

//example of a computationally intensive action with UI updates private void do_work() {

Thread thread = new Thread(new Runnable() { public void run() {

text_string=R.string.start; background_color = Color.DKGRAY; mHandler.post(mUpdateResults);

computation(l); text_string=R.string.first; background_color = Color.BLUE; mHandler.post(mUpdateResults);

computation(2); text_string=R.string.second; background_color = Color.GREEN; mHandler.post(mUpdateResults);

thread.start();

final static int SIZE=1000; //large enough to take some time double tmp;

private void computation(int val) { for(int ii=0; ii<SIZE; ii++)

tmp=val*Math.log(ii+1)/Math.log1p(jj+1);

Character Building Thought Power

Character Building Thought Power

Character-Building Thought Power by Ralph Waldo Trine. Ralph draws a distinct line between bad and good habits. In this book, every effort is made by the writer to explain what comprises good habits and why every one needs it early in life. It draws the conclusion that habits nurtured in early life concretize into impulses in future for the good or bad of the subject.

Get My Free Ebook


Post a comment