2014-04-28 58 views
0

我有一個菜單按鈕,當我單擊它時,它會向雲發送一些數據。在發送數據時,我會顯示一個進度對話框。每件事情都順其自然,似乎很好,我可以多次按下按鈕,並將數據正確發送到雲端。 但是當我去退出活動我得到一個錯誤,說有一個窗口泄漏:即使在調用解除後也會出現進度對話框泄漏的窗口錯誤

com.android.internal.policy.impl.PhoneWindow$DecorView{4321fd38 V.E..... R......D 0,0-1026,288} that was originally added here 

的「這裏」指的是,當我饞我的進度對話框。

這裏是我的代碼:

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
progressDialog = ProgressDialog.show(CruiseDetailRollCallActivity.this, "", "Loading...", true);//set up & show progress dialog 

switch(item.getItemId()){ 
case R.id.menu_roll_call_opt_in: 
    //saveing something into Parse -- (a database online, check Parse.com if you want more info, but just treat this like I am saving something into the cloud) 
    currentUser.put("somethingBoolean", false); 
    currentUser.saveInBackground(new SaveCallback(){ 

    @Override 
    public void done(ParseException e) { //once data has been put into the cloud 
     progressDialog.dismiss();//dismiss the dialog 
     supportInvalidateOptionsMenu();//refreshes the options menu 
    } 
    }); 

    return true; 

default: 
    return super.onOptionsItemSelected(item); 
} 
} 

我應該指出,這不是我的崩潰申請,但僅僅是顯示錯誤。我不知道爲什麼會發生,我覺得我不應該忽略它。

編輯:發現我的錯誤。這是失敗的,因爲作品是因爲我在回到操作欄上,並且進度對話框將被創建,但從未被解僱,因爲它只是在完成的代碼中被解散。

+0

你應該解僱'進展Dialog'在'的onStop()。' –

+0

@SimplePlan見我在下面對你的回答發表評論。 onStop()是可驅動的,取決於操作系統決定做什麼,onStop()可能永遠不會被執行。 – mttdbrd

回答

1

這是失敗的,因爲作品是因爲我打回操作欄,進度對話框將被創建,但從來沒有被駁回,因爲它只是在完成的代碼中被解散。

我感動

progressDialog = ProgressDialog.show(CruiseDetailRollCallActivity.this, "", "Loading...", true);//set up & show progress dialog 

case R.id.menu_roll_call_opt_in: 
//saveing something into Parse -- (a database online, check Parse.com if you want more info, but just treat this like I am saving something into the cloud) 
currentUser.put("somethingBoolean", false); 
currentUser.saveInBackground(new SaveCallback(){ 

@Override 
public void done(ParseException e) { //once data has been put into the cloud 
    progressDialog.dismiss();//dismiss the dialog 
    supportInvalidateOptionsMenu();//refreshes the options menu 
} 
}); 

return true; 

所以看起來像這樣

case R.id.menu_roll_call_opt_in: 
progressDialog = ProgressDialog.show(CruiseDetailRollCallActivity.this, "", "Loading...", true);//set up & show progress dialog 
//saveing something into Parse -- (a database online, check Parse.com if you want more info, but just treat this like I am saving something into the cloud) 
currentUser.put("somethingBoolean", false); 
currentUser.saveInBackground(new SaveCallback(){ 

@Override 
public void done(ParseException e) { //once data has been put into the cloud 
    progressDialog.dismiss();//dismiss the dialog 
    supportInvalidateOptionsMenu();//refreshes the options menu 
} 
}); 

return true; 
1

我的猜測是,當您將傳遞到currentUser.saveInBackground(new SaveCallback()...時,您正在將此活動泄漏到currentUser對象中。您剛剛創建的SaveCallback類現在對活動有很強的參考。即使您退出該方法,它也不會被垃圾收集。你應該使用WeakReference然後它可以被垃圾收集。

WeakReference<CruiseDetailRollCallActivity> weakRef = new WeakReference<CruiseDetailRollCallActivity>(CruiseDetailRollCallActivity.this) 

然後,通過weakRef到ProgressDialog構造函數:

progressDialog = ProgressDialog.show(weakRef.get(), "", "Loading...", true); 

每當你繞過Android中的背景下,檢查,看看是否需要一個WeakReference的,因此它可以被垃圾收集。泄漏整個應用程序很容易。

+0

我不完全理解這一點,因爲我在我的應用程序的其他地方運行了類似的代碼,並且不會拋出錯誤。但是你的代碼確實有效。 – Sree

+0

然後,您應該修復所有其他代碼。您在設備上導致內存泄漏。人們不會購買你的應用程序! :) – mttdbrd

+1

我寫了一篇關於這個問題的博客文章。值得您花時間來了解WeakReferences和垃圾收集,特別是如果您將使用Android。該系統基本上被設計爲產生內存泄漏。而且在過去的幾天似乎在SO上出現了很多。你可以在這裏閱讀更長的解釋:http:// tmblr。co/ZSJA4p13azutu – mttdbrd

相關問題