2013-02-08 110 views
2

我有這個過程,通過一些「如果」 S取決於如果用戶插入或彈出存儲筆驅動器上運行:Android的 - 如何避免兩個runOnUIThread之間的僵局調用

int userStatus = StopActivity.USER_HAS_NEVER_INSERTED_MEMORY; 

while (true) { 

    File usbDirectoryFile = new File(usbDirectory); 

    if (usbDirectoryFile.exists()) { 

     verMasInfoDirectory = usbDirectory + File.separator + "vermasinfo"; 
     File verMasInfoDirectoryFile = new File(verMasInfoDirectory); 

     if (verMasInfoDirectoryFile.exists()) { 

      break; 

     } else if (userStatus != StopActivity.USER_HAS_BEEN_NOTIFIED) { 

      userStatus = StopActivity.USER_HAS_BEEN_NOTIFIED; 
      runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        Toast.makeText(StopActivity.this, R.string.stop_activity_directory_not_exists_toast_text, Toast.LENGTH_LONG).show(); 
       } 
      }); 
     } 
    } else if (userStatus == StopActivity.USER_HAS_BEEN_NOTIFIED) { 

     userStatus = StopActivity.USER_HAS_NOT_BEEN_NOTIFIED; 
     runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        Toast.makeText(StopActivity.this, R.string.stop_activity_ejected_memory_toast_text, Toast.LENGTH_LONG).show(); 
       } 
     }); 
    } 
    usbDirectoryFile = null; 
} 

的問題是,當用戶快速插入/彈出筆驅動器,兩次調用runOnUIThread都會導致死鎖。

我該如何避免這種死鎖?

在此先感謝。

回答

3

這些調用不會導致死鎖。首先,它們由系統一次運行一個。也就是說,一個在事件線程上運行(在事件線程上)完成(直到run()方法返回),另一個被出隊並由事件線程運行。其次,可運行程序不是鎖定資源,所以沒有任何死鎖原因。

也許您同時關注屏幕上的兩個Toast(因爲每個Toastshow()返回後都會顯示一段時間)。唯一的問題是,一個會隱藏另一個;但是,仍然沒有死鎖。

如果您的應用程序處於死鎖狀態,則問題在其他地方。

+0

按照您的回答(無視死鎖),我在該時段結束前添加了一個'Thread.sleep(100)',現在完美工作。 只是爲了讓這個清楚:你知道爲什麼在很多情況下睡覺的東西會起作用嗎? –

+1

@Jorgesmash - 我懷疑你的循環將事件線程隊列中的runnables放置得比他們可能消耗的速度快得多,最終壓倒了系統。我不太清楚你期望循環做什麼,但是如果我正確地追蹤它,它會盡快彈出Toasts,等待某個文件出現。我不知道這會是什麼目的,但它似乎不是通知用戶有關事情的正確方法。 –

相關問題