我有一个菜单按钮,当我点击它时,它会将一些数据发送到云端。在发送数据时,我会显示一个进度对话框。每件事情都很顺利,看起来很好,我可以按下按钮多次,数据被正确发送到云端。 但是当我退出活动时,我得到一个错误,说有一个窗口泄漏:
com.android.internal.policy.impl.PhoneWindow$DecorView{4321fd38 V.E..... R......D 0,0-1026,288} that was originally added here
" 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 :(得分:1)
我的猜测是,当您将currentUser
传递给CruiseDetailRollCallActivity
时,您将活动泄露到currentUser.saveInBackground(new SaveCallback()...
对象中。您刚刚创建的SaveCallback
类具有对Activity的强引用。即使退出方法,它也永远不会被垃圾回收。你应该使用WeakReference
然后它可以被垃圾收集。
WeakReference<CruiseDetailRollCallActivity> weakRef = new WeakReference<CruiseDetailRollCallActivity>(CruiseDetailRollCallActivity.this)
然后,将weakRef传递给ProgressDialog构造函数:
progressDialog = ProgressDialog.show(weakRef.get(), "", "Loading...", true);
每当你在Android中传递Context时,检查你是否需要WeakReference以便它可以被垃圾收集。泄漏整个应用程序很容易。
答案 1 :(得分: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;