2013-05-14 58 views
0

我試圖在我的應用程序中實現超時行爲。實際發生超時之前5秒鐘還應該有警告(alertdialog)。ScheduledExecutorService作爲超時顯示沒有AlertDialog

我想使用ScheduledExecutorService來做到這一點。

這是迄今爲止我的相關代碼:

private final Context context = this; 

private ScheduledExecutorService sExService = Executors.newScheduledThreadPool(2); 

private RunnableScheduledFuture<?> sFutureTimeout; 
private RunnableScheduledFuture<?> sFutureDisconnect; 

private final Runnable timeoutRunnable = new Runnable(){ 
    @Override 
    public void run() {  
     showTimeoutAlertDialog(); 
    } 
}; 
private final Runnable disconnectRunnable = new Runnable(){ 
    @Override 
    public void run() { 
     disconnect(); 
    } 
}; 

和處理超時行爲的方法:

private void setTimeout(){ 
    sFutureTimeout = (RunnableScheduledFuture<?>) sExService.schedule(timeoutRunnable, 5, TimeUnit.SECONDS); 
} 

的setTimeout被調用的onCreate(),所以之後的應用程序應斷開5S發射。

private void showTimeoutAlertDialog(){ 

    new AlertDialog.Builder(context) 
      .setTitle("Disconnect in 5s") 
      .setCancelable(false) 
      .setPositiveButton("Abort", 
        new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int id) { 
          sFutureDisconnect.cancel(false); 
          setTimeout(); 
         } 
        }).show(); 

    sFutureDisconnect = (RunnableScheduledFuture<?>) sExService.schedule(disconnectRunnable, 5, TimeUnit.SECONDS); 
} 

這裏是我所面臨的問題:

  • 如果運行的稱爲「setTimeout的」設置爲「disconnectRunnable」,它工作正常,5秒後,應用程序斷開連接。

  • 當我將它設置爲'timeoutRunnable'時,alertDialog未顯示+應用程序永遠不會斷開連接,即使'disconnectRunnable'應該在「showTimeoutAlertDialog」中調用5s之後!

我認爲ScheduledExecutorService在這裏出了問題,但我找不到解決方案。

謝謝您的幫助:)

回答

0

您正在嘗試從UI線程顯示AlertDialog沒有那麼它不會有任何效果的方法showTimeoutAlertDialog()是從預定的線程池創建的工作線程調用。您可以使用Handler您的目的:

public class MyActivity extends Activity { 

    private final Context context = this; 

    private static Handler mHandler = new Handler(); 

    private final Runnable timeoutRunnable = new Runnable(){ 
     @Override 
     public void run() { 
      showTimeoutAlertDialog(); 
     } 
    }; 
    private final Runnable disconnectRunnable = new Runnable(){ 
     @Override 
     public void run() { 
      disconnect(); 
     } 
    }; 

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

    private void disconnect() { 
     Log.e("MyActivity", "Disconnected"); 
    } 

    private void setTimeout(){ 
     mHandler.postDelayed(timeoutRunnable, 5000); 
    } 

    private void showTimeoutAlertDialog(){ 

     new AlertDialog.Builder(context) 
       .setTitle("Disconnect in 5s") 
       .setCancelable(false) 
       .setPositiveButton("Abort", 
         new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, int id) { 
           mHandler.removeCallbacks(disconnectRunnable); 
           setTimeout(); 
          } 
         }).show(); 

     mHandler.postDelayed(disconnectRunnable, 5000); 
    } 
} 
+0

謝謝。我之前嘗試過使用Handler。我不知道.removeCallbacks(r)方法:) – Cabus 2013-05-14 10:58:33

+0

還有一個問題:現在線程怎麼樣?整個超時行爲現在在ui-thread上運行,不是嗎?如果是的話,是否有一個解決方法來保持超時功能在一個單獨的線程? – Cabus 2013-05-14 11:01:20

+0

如果在此處執行長時間運行的作業,則可以在disconnect()方法中啓動一個新線程。 ''mHandler.postDelayed(...)''不會阻塞UI線程,它只會將Runnable放置在消息隊列中並將其延遲指定的時間。如果需要,您也可以從此Runnable啓動一個新線程。 – makovkastar 2013-05-14 11:06:34