应用程序关闭时,在适配器内关闭AlertDialog

时间:2017-02-13 09:04:07

标签: android android-alertdialog

每次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);
            }

        }
    }

2 个答案:

答案 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();

            }
}