2011-12-15 95 views
0

我有一個運行2個線程的應用程序。第一個是以1秒爲間隔更新圖形,第二個是以60秒間隔更新另一個圖形。第二項任務需要很長時間,因爲它在互聯網上查詢某個服務器3次,可能並不總是可用,即使這樣做需要5到7秒才能執行。Android - 爲什麼第二個線程停止執行第一個線程?

發生了什麼事情是當我啓動第二個線程時,它會暫停第一個線程的執行,而這不是我想要的,我希望兩者都同時運行。在Youtube視頻中,您可以看到正在運行的應用程序的結果。 http://youtu.be/l7K5zSWzlxI 「thread_updater1s」正在角落裏運行一個綠色圖形,大量讀數和一個計時器,所以你清楚地看到它停頓了11秒。

1)首先,爲什麼會發生這種情況?如何解決它?

2)我知道我可能不會正確啓動線程。我很難理解如何使某些東西在Java中以間隔循環運行,並且我的代碼對於一個圖形/花紋可以很好地工作。現在,當我在單獨的線程中有2個循環時,我不知道它們爲什麼不同時執行。

下面是代碼:

public class LoopExampleActivity extends Activity { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.main); 
    thread_updater1s.start(); 
    thread_updater2.start(); 
}// end of onCreate 

final Runnable r1s = new Runnable() { 
    public void run() { 
     do_1s_updates(); // those are very quick http calls to the local API server 
    }     // to get data nessessary for some plot. 
         // They have 1s timeout as well but rarely timeout 
}; 

final Runnable r2 = new Runnable() { 
    public void run() { 
     do_large_updates(); //This makes 7 long call over the Internet to the slow https 
          //server once every 60s. Has 10s timeout and sometimes takes as much as 
          //7s to execute 
     } 
}; 

Thread thread_updater1s = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       handler.post(r1s); 
       sleep(1000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

Thread thread_updater2 = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       handler2.post(r2); 
       sleep(60000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

}

PS。請原諒和翔實的我只有Java代碼15天迄今沒有任何事先經驗或教訓。

回答

0

您需要在線程中發出http請求(不是發佈的runnables)。然後,當您下載數據時,您將使用該數據創建一個可運行的數據,該數據將更新圖形並將其發佈爲可由UI線程執行的可運行數據。下面是一個示例:

public class LoopExampleActivity extends Activity { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.main); 
    thread_updater1s.start(); 
    thread_updater2.start(); 
}// end of onCreate 

Thread thread_updater1s = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       final Object data = getDataFromServer1(); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         updateGraph1(data); 
        } 
       ); 
       sleep(1000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

Thread thread_updater2 = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       final Object data = getDataFromServer2(); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         updateGraph2(data); 
        } 
       ); 
       sleep(60000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

顯然,通過表示您的數據的適當類更改最終對象數據。

0

handler.post將runnable推送到主(UI)線程的消息隊列中,以便在主線程上執行。

所以你在做什麼是每個睡眠間隔,你發送消息到主線程運行該功能。顯然,主線程不能同時運行兩件事,所以這就是爲什麼一個runnable會延遲下一個runnable的原因。

您可能想要在單獨的線程中執行runnable的工作 - 您爲什麼開始使用處理程序?如果您直接撥打do_1s_updatesdo_large_updates而不是通過處理程序&可運行,會發生什麼情況?

+0

謝謝,這是一個大開眼界!不知道處理程序發佈到主UI。但是,我怎樣才能使線程循環出來,我可以做thread_updater1s.post()在結束做出一個循環嗎? – 2011-12-15 21:38:59

+0

我使用了處理程序,因爲這是我在網上找到的第一個例子,可以輕鬆地停下來做一個循環。我看到還有HandlerThread就是我需要的,所以我不需要改變我的應用程序呢? – 2011-12-15 22:13:08

相關問題