每次AlertDialog
显示且应用程序关闭或销毁时,我都会在logcat has leaked window
中收到此错误。我知道使用下面的onDestroy()
方法会删除该错误,但只有AlertDialog
位于活动内部时才有效。但是在我的情况下,我正在使用适配器内部的AlertDialog
,该代码显示在下面的代码中
@Override
public void onDestroy(){
super.onDestroy();
if(alertDialog != null && alertDialog.isShowing()) {
alertDialog.cancel();
}
}
Logcat错误。
Activity com.test.example.MovieList has leaked window
com.android.internal.policy.impl.PhoneWindow$DecorView{1ed0b473 V.E..... R.......
0,0-1080,543} that was originally added here at android.view.ViewRootImpl.<init>
(ViewRootImpl.java:363)
适配器
public class MyAdapter extends RecyclerView.Adapter <MyAdapter.ViewHolder>{
private List<Movies> moviesList;
private Context mContext;
AlertDialog alertDialog;
public MyAdapter (Context context, List<Movies> list) {
mContext = context;
moviesList= list;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
View view = View.inflate(parent.getContext(), R.layout.movies, null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int viewType) {
final Movies movies = moviesList.get(holder.getAdapterPosition());
final String id = movies.getId()
holder.title.setText(movies.getTitle());
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.AppCompatAlertDialogStyle);
builder.setTitle(R.string.dialog_title);
builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
moviesList.remove(holder.getAdapterPosition());
DBHelper db = new DBHelper (mContext);
db.deleteMovie(movie);
notifyDataSetChanged();
db.close();
dialog.dismiss();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog = builder.create();
alertDialog.show();
return false;
}
});
}
@Override
public int getItemCount() {
return (moviesList != null? moviesList.size():0);
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
ViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.movie_title);
}
}
}
答案 0 :(得分:0)
我有一个(可能)可能的解决方案。
替换
AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.AppCompatAlertDialogStyle);
使用
AlertDialog.Builder builder = new AlertDialog.Builder(mContext.getApplicationContext(), R.style.AppCompatAlertDialogStyle);
注意:使用“应用程序”上下文替换“活动”的上下文。导致您的活动可能在警报对话框中引用,导致此泄漏。
答案 1 :(得分:0)
您可以使用界面设置回调,通知您的活动。
您的适配器
public class MyAdapter extends RecyclerView.Adapter <MyAdapter.ViewHolder>{
private List<Movies> moviesList;
private Context mContext;
AlertDialog alertDialog;
private AdapterCallback callback;
public MyAdapter (Context context, List<Movies> list, AdapterCallback callback) {
mContext = context;
moviesList= list;
this.callback=callback;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mContext = parent.getContext();
View view = View.inflate(parent.getContext(), R.layout.movies, null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int viewType) {
final Movies movies = moviesList.get(holder.getAdapterPosition());
final String id = movies.getId()
holder.title.setText(movies.getTitle());
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if(this.callback!=null)
callback.onButtonLongPress(holder.getAdapterPosition())
return false;
}
});
}
@Override
public int getItemCount() {
return (moviesList != null? moviesList.size():0);
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
ViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.movie_title);
}
}
public interface AdapterCallback{
void onButtonLongPress(int position);
}
}
**Your Activity**
public MyActivity extends Activity implement MyAdapter.AdapterCallback{
...
void onButtonLongPress(final int position){
AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.AppCompatAlertDialogStyle);
builder.setTitle(R.string.dialog_title);
builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
moviesList.remove(holder.getAdapterPosition());
DBHelper db = new DBHelper (mContext);
db.deleteMovie(movie);
notifyDataSetChanged();
db.close();
dialog.dismiss();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog = builder.create();
alertDialog.show();
}
}