如何处理android中的致命异常(坏标记异常)

时间:2015-10-22 15:40:40

标签: java android

这是我在按钮点击时删除所选项目的代码,我在此代码中添加了“警告”对话框,“我添加此警报”框后,发生致命错误异常。

 public class MycustomAdapter extends BaseAdapter implements ListAdapter {
    public ArrayList<category> list = new ArrayList<category>();
    public Context context;



    public MycustomAdapter(ArrayList<category> list, Context context) {
        this.list = list;
        this.context = context;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int pos) {
        return list.get(pos);
    }

    @Override
    public long getItemId(int position) {
        return list.get(position).getId();
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.row, null);
        }

        //Handle TextView and display string from your list
        TextView listItemText = (TextView)view.findViewById(R.id.lblreload
        );
        listItemText.setText(list.get(position).getName());

        listItemText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                category row = (category) list.get(position);
                int selected_id = row.getId();
                String budget = row.getName();

                Intent myIntent = new Intent(context, addbudget.class);
                myIntent .putExtra("passed data key",budget);
                myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(myIntent);
            }
        });

        //Handle buttons and add onClickListeners
       TextView deleteBtn = (TextView)view.findViewById(R.id.delete_btn);

        deleteBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(context)
                        .setTitle("Delete entry")
                        .setMessage("Are you sure you want to delete this entry?")
                        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                SQLiteDatabase db = new DBhelper(context).getWritableDatabase();
                                db.delete(DBhelper.TABLE1, DBhelper.C_ID + "=?", new String[] {Integer.toString(list.get(position).getId())});
                                db.close();
                                list.remove(position);
                                notifyDataSetChanged();

                            }
                        })
                        .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                // do nothing
                            }
                        })
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();

            }
        });


        return view;
    }
}

这是我点击删除按钮时遇到的致命错误异常。

 22 20:50:56.546  28837-28837/com.example.username.weddingplanning
 E/AndroidRuntime﹕ FATAL EXCEPTION: main
     android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
             at android.view.ViewRootImpl.setView(ViewRootImpl.java:811)
             at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:265)
             at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:73)
             at android.app.Dialog.show(Dialog.java:282)
             at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
             at com.example.username.weddingplanning.MycustomAdapter$2.onClick(MycustomAdapter.java:101)
             at android.view.View.performClick(View.java:4439)
             at android.view.View$PerformClick.run(View.java:18398)
             at android.os.Handler.handleCallback(Handler.java:725)
             at android.os.Handler.dispatchMessage(Handler.java:92)
             at android.os.Looper.loop(Looper.java:176)
             at android.app.ActivityThread.main(ActivityThread.java:5299)
             at java.lang.reflect.Method.invokeNative(Native Method)
             at java.lang.reflect.Method.invoke(Method.java:511)
             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
             at dalvik.system.NativeStart.main(Native Method)

我已经在堆栈溢出中经历了类似的问题,但我没有得到它。我在CustomAdapter类中有这个删除按钮,而不是在Activity类中。

1 个答案:

答案 0 :(得分:1)

AlertDialog.Builder不仅需要任何上下文,它还需要一个活动。更确切地说,它需要显示ListView的活动。

所以问题是“我们如何从上下文中获取活动”?

首先,您需要使用包含ListView的活动来初始化您的适配器:

// assuming 'this' means the activity:
adapter = new MyCustomAdapter(myList, this);

然后,您可以在'MyCustomAdapter.java'的'getView()'方法中执行以下操作(假设该活动名为'MyActivity'):

deleteBtn.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {

        // you know the condition will be true,
        // but for formal reasons make sure anyway:
        if (context instanceof MyActivity)
        {
            new AlertDialog.Builder((MyActivity)context)
                    .setTitle("Delete entry")
                    .setMessage("Are you sure you want to delete this entry?")
                    .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                     // and so on...
                    })
                    .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // do nothing
                        }
                    })
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .show();

        }
     }
});

为了安全地进行数据库调用,仍然可以编写

SQLiteDatabase db = new DBhelper(context.getApplicationContext()).getWritableDatabase();