Android 后台线程实例


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

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

创建新的线程

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

java代码:

  1. // This method is called on the main GUI thread.  
  2. private void mainProcessing() {  
  3. // This moves the time consuming operation to a child thread.  
  4. Thread thread = new Thread(null, doBackgroundThreadProcessing, “Background”);  
  5. thread.start();  
  6. }  
  7.   
  8. // Runnable that executes the background processing method.  
  9. private Runnable doBackgroundThreadProcessing = new Runnable() {  
  10. public void run() {  
  11. backgroundThreadProcessing();  
  12. }  
  13. };  
  14.   
  15. // Method which does some processing in the background.  
  16. private void backgroundThreadProcessing() {  
  17. [ ... Time consuming operations ... ]  
  18. }   

为GUI操作同步线程

       无论何时你在GUI环境中使用后台线程,在创建和修改图形组件之前,同步子线程和主线程是很重要的。
Handler类允许你向创建Handler类的线程委派一个方法。使用Handler类,你可以借用post方法来从后台线程通知更新UI。下面的例子显示了使用Handler来更新GUI线程的框架代码:

  1. // Initialize a handler on the main thread.  
  2. private Handler handler = new Handler();  
  3.   
  4. private void mainProcessing() {  
  5. Thread thread = new Thread(null, doBackgroundThreadProcessing, “Background”);  
  6. thread.start();  
  7. }  
  8. private Runnable doBackgroundThreadProcessing = new Runnable() {  
  9. public void run() {  
  10. backgroundThreadProcessing();  
  11. }  
  12. };  
  13. // Method which does some processing in the background.  
  14. private void backgroundThreadProcessing() {  
  15. [ ... Time consuming operations ... ]  
  16. handler.post(doUpdateGUI);  
  17. }  
  18. // Runnable that executes the update GUI method.  
  19. private Runnable doUpdateGUI = new Runnable() {  
  20. public void run() {  
  21. updateGUI();  
  22. }  
  23. };  
  24. private void updateGUI() {  
  25. [ ... Open a dialog or modify a GUI element ... ]  
  26. }   
Handler类允许你延迟委派或在特定的时间来执行,使用postDelayed和postAtTime方法。

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

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

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

        1. 重命名refreshEarthquakes方法为doRefreshEarthquakes。
  1. private void doRefreshEarthquakes() {  
  2. [ ... previous refreshEarthquakes method ... ]  
  3. }   
 2. 创建一个新的refreshEarthquakes方法。它需要启动一个执行新命名的doRefreshEarthquakes方法的线程。
  1. private void refreshEarthquakes() {  
  2. Thread updateThread = new Thread(null, backgroundRefresh,“refresh_earthquake”);  
  3. updateThread.start();  
  4. }  
  5.   
  6. private Runnable backgroundRefresh = new Runnable() {  
  7. public void run() {  
  8. doRefreshEarthquakes();  
  9. }  
  10. };   

相关内容