使用后台工作者线程

  

为了保持应用程序的持续响应性,一个好的习惯是把所有慢的、耗时的操作移出主线程,放到子线程中。

 

所有的Android应用程序组件——包括ActivityServiceBroadcast Receiver,都运行在主线程。因此,任何组件中的耗时操作都将阻塞其它的组件,包括Service和可见的Activity

 

使用后台线程,对于避免第2章中曾描述的“应用程序无响应”对话框的情况是至关重要的。在Android中定义的无响应是指:Activity5秒内不响应任何输入事件(例如一个按键事件)和Broadcast Receiver10秒未完成onReceive的处理操作。

 

不仅仅是你要避免这种情况,甚至是你都不应该能遇到这种情况。为耗时的处理使用后台线程,包括文件操作、网络搜索、数据库交互和复杂的计算。

 

创建新的线程

 

你可以使用Android中的Handler类和java.lang.Thread中的线程类来创建和管理子线程。下面的框架代码显示了如何把操作移到子线程中:

 

// This method is called on the main GUI thread.

private void mainProcessing() {

// This moves the time consuming operation to a child thread.

Thread thread = new Thread(null, doBackgroundThreadProcessing, “Background”);

thread.start();

}

 

// Runnable that executes the background processing method.

private Runnable doBackgroundThreadProcessing = new Runnable() {

public void run() {

backgroundThreadProcessing();

}

};

 

// Method which does some processing in the background.

private void backgroundThreadProcessing() {

[ ... Time consuming operations ... ]

}

 

GUI操作同步线程

 

无论何时你在GUI环境中使用后台线程,在创建和修改图形组件之前,同步子线程和主线程是很重要的。

 

Handler类允许你向创建Handler类的线程委派一个方法。使用Handler类,你可以借用post方法来从后台线程通知更新UI。下面的例子显示了使用Handler来更新GUI线程的框架代码:

hread:

 

// Initialize a handler on the main thread.

private Handler handler = new Handler();

 

private void mainProcessing() {

Thread thread = new Thread(null, doBackgroundThreadProcessing, “Background”);

thread.start();

}

private Runnable doBackgroundThreadProcessing = new Runnable() {

public void run() {

backgroundThreadProcessing();

}

};

// Method which does some processing in the background.

private void backgroundThreadProcessing() {

[ ... Time consuming operations ... ]

handler.post(doUpdateGUI);

}

// Runnable that executes the update GUI method.

private Runnable doUpdateGUI = new Runnable() {

public void run() {

updateGUI();

}

};

private void updateGUI() {

[ ... Open a dialog or modify a GUI element ... ]

}

 

Handler类允许你延迟委派或在特定的时间来执行,使用postDelayedpostAtTime方法。

 

对于修改View的特殊情形,UIThreadUtilities类提供了runOnUIThread方法,来让你迫使一个方法运行在和特定ViewActivity或对话框相同的线程上。

 

在程序组件中,NotificationIntent总是在GUI线程中接收和处理的。对于其他的情况,如与GUI线程中创建的对象(例如View)进行显式的交互或显示消息(如Toast),这些操作都必须请求(Invoke)到主线程中执行。

 

移动EarthquakeService到后台线程中

 

下面的代码演示了如何移动EarthquakeService中的网络搜索和XML解析的操作到一个后台线程中:

 

1. 重命名refreshEarthquakes方法为doRefreshEarthquakes

 

private void doRefreshEarthquakes() {

[ ... previous refreshEarthquakes method ... ]

}

 

2. 创建一个新的refreshEarthquakes方法。它需要启动一个执行新命名的doRefreshEarthquakes方法的线程。

 

private void refreshEarthquakes() {

Thread updateThread = new Thread(null, backgroundRefresh,“refresh_earthquake”);

updateThread.start();

}

 

private Runnable backgroundRefresh = new Runnable() {

public void run() {

doRefreshEarthquakes();

}

};

posted on 2009-08-19 10:04  xirihanlin  阅读(1844)  评论(0编辑  收藏  举报