2011-03-21 86 views
0

我有一個正在執行數據更新的服務。我有一個活動,將監聽器附加到服務上(通過本地綁定)。偵聽器接收進度更新。在收到進度更新後,它會安排一個可運行的UI線程運行。這裏是(更新以顯示完整清單)代碼:如何從Runnable檢測Activity是否處於可用狀態?

public class MyActivity extends Activity { 

    static final int UPDATE_DIALOG = 0; 
    ProgressDialog updateDialog; 

    private TaskService taskService; 

    private ServiceConnection taskServiceConnection = new ServiceConnection() { 

    private final TaskServiceObserver taskServiceObserver = new TaskServiceObserver() { 

     public void updateProgress(final int progress, final int total) { 
     runOnUiThread(new Runnable() { 
      public void run() {   
      if (updateDialog == null || !updateDialog.isShowing()) { 
       showDialog(UPDATE_DIALOG); 
      } 
      updateDialog.setProgress(progress); 
      } 
     }); 
     } 

     public void updateCompleted() { 
     runOnUiThread(new Runnable() { 
      public void run() { 
      dismissDialog(UPDATE_DIALOG); 
      startNextActivity(); 
      } 
     }); 
     } 
    }; 

    public void onServiceConnected(ComponentName name, IBinder binder) { 
     taskService = ((LocalBinder) binder).getService(); 

     taskService.addObserver(taskServiceObserver); 
    } 

    public void onServiceDisconnected(ComponentName name) { 
     taskService.removeObserver(taskServiceObserver); 
     taskService = null; 
    } 

    }; 

    protected void onStart() { 
    super.onStart(); 

    Intent intent = new Intent(this, TaskService.class); 
    startService(intent); 
    bindService(intent, taskServiceConnection, Context.BIND_AUTO_CREATE); 
    } 

    protected void onStop() { 
    super.onStop(); 

    if (taskService != null) { 
     unbindService(taskServiceConnection); 
    } 
    } 

    protected Dialog onCreateDialog(int id) { 
    switch (id) { 
    case UPDATE_DIALOG: 
     updateDialog = new ProgressDialog(this); 
     updateDialog.setTitle("My App"); 
     updateDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     updateDialog.setMessage("Preparing to run for the first time..."); 
     return updateDialog; 
    default: 
     return null; 
    } 
    } 

} 

如果我點擊主頁按鈕時,對話框顯示,然後返回到應用程序,我得到了showDialog線崩潰。通過調試器,我可以確定活動處於完成狀態。

什麼是適當的檢查放在我的runnable,這將確定是否可以安全地撥打showDialog

+1

如果您顯示監聽器+服務代碼,我們可能會給出更好的答案。 – 2011-03-21 15:11:26

回答

0

當活動進入暫停狀態(覆蓋)時,如果有必要,當活動重新開始時(覆蓋onResume),我將個人關閉進度對話框。您可能會因爲在其他單獨對象(您的對話框)中引用您的活動而導致內存泄漏

0

您應該在onPause方法中分離偵聽器,以便您的活動進入後臺,偵聽器不會觸發並嘗試更新UI。

+0

我目前只在'onStop'中分離監聽器,所以我一定會在'onPause'中這樣做。儘管如此,還是有可能有這種交錯的事件: 1.服務通知監聽器 2.聽衆增加了一個可運行在UI更新進度 3.'onPause'分離聽衆 4.運行的嘗試中顯示對話框已暫停的活動 – 2011-03-21 16:45:50

+0

當然,但它有助於瞭解您的服務如何與活動進行通信。 – 2011-03-21 16:47:55

+0

今天晚上我會發布更完整的源代碼。謝謝您的幫助。 – 2011-03-21 17:08:01

0

我最終選擇的解決方案是創建一個標記taskServiceBound,該標記在綁定到服務onStart後設置爲true,並在從onStop中的服務解除綁定之前設置爲false。因爲該標誌在UI線程上更新,所以我可以使用它來關閉updateProgressupdateCompleted中的Runnables。例如:

public void updateCompleted() { 
    runOnUiThread(new Runnable() { 
     public void run() { 
     if (taskServiceBound) { 
      dismissDialog(UPDATE_DIALOG); 
      startNextActivity(); 
     } 
     } 
    }); 
    } 
相關問題