空对象引用上的closeDatabase()'

Posted

技术标签:

【中文标题】空对象引用上的closeDatabase()\'【英文标题】:closeDatabase()' on a null object reference [duplicate]空对象引用上的closeDatabase()' 【发布时间】:2017-12-28 13:41:38 【问题描述】:

我的代码有问题,它说

07-22 21:40:43.059 28529-28529/plp.plpedia.developer.larriane.my_plpedia E/androidRuntime: FATAL EXCEPTION: main

进程:plp.plpedia.developer.larriane.my_plpedia,PID:28529 java.lang.RuntimeException:无法销毁活动plp.plpedia.developer.larriane.my_plpedia/plp.plpedia.developer.larriane.my_plpedia.MainNotes:java.lang.NullPointerException:尝试调用虚拟方法'void plp.plpedia .developer.larriane.my_plpedia.NotesCRUDManager.closeDatabase()' 在空对象引用上 在 android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4874) 在 android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4892) 在 android.app.ActivityThread.access$1600(ActivityThread.java:218) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1772) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:145) 在 android.app.ActivityThread.main(ActivityThread.java:6917) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199) 引起:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void plp.plpedia.developer.larriane.my_plpedia.NotesCRUDManager.closeDatabase()” 在 plp.plpedia.developer.larriane.my_plpedia.MainNotes.onDestroy(MainNotes.java:60)

这是我的 NotesCRUDManager.java 数据库。

    public class NotesCRUDManager 

        private SQLiteDatabase db;
        private Context context;
        private String DBName = "NotesDB";
        private String TableName = "mynotes";
        private List<Integer> ids_list = new ArrayList<Integer>();
        private List<String> titles_list = new ArrayList<String>();
        private List<String> notes_list = new ArrayList<String>();
        private List<String> remark_list = new ArrayList<String>();

        NotesCRUDManager(Context context) 

            this.context = context;
            // As soon as we call this class our database should be created or opened
            AccessDatabase();
            AccessNotesTable();
        

        // Opening database
        public void AccessDatabase() 
            // create database named as "Catalog"
            // context.MODE_PRIVATE indicates this database can only be access through this application
            db = context.openOrCreateDatabase(DBName, context.MODE_PRIVATE, null);
        

        // Selecting our table
        public void AccessNotesTable() 

            db.execSQL("CREATE TABLE IF NOT EXISTS " + TableName + "(_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, note TEXT, remark TEXT)");
        

        // Inserting product into table
        public void InsertNote(String title, String note, String remark) 

            ContentValues values = new ContentValues(); // create an instance of ContentValues
            values.put("title", title); // parameters are (key, value) but the key = columnName in our Database Table
            values.put("note", note);
            values.put("remark", remark);
            //db.insert() is similar to prepared statement in Java. It will prevent SQL Injections
            db.insert(TableName, null, values);
        

        public void EditNote(int id, String title, String note, String remark) 

            ContentValues values = new ContentValues(); // create an instance of ContentValues
            values.put("title", title); // parameters are (key, value) but the key = columnName in our Database Table
            values.put("note", note);
            values.put("remark", remark);
            //db.update removes the risk of SQL Injection
            db.update(TableName, values, "_id = ?", new String[]"" + id);
        

        public void DeleteNote(int id) 
            // simple sql statement
            db.execSQL("DELETE FROM " + TableName + " WHERE _id = " + id + ";");
        

        // Showing all rows from table
        public void showNote(List<Integer> ids_list, List<String> titles_list, List<String> notes_list, List<String> remark_list) 

            // this will execute select query
            Cursor cursor = db.rawQuery("SELECT * FROM " + TableName + " ORDER BY _id DESC", null);
            // getting data from all rows
            while (cursor.moveToNext()) 
                //filling up the arraylist with database columns
                ids_list.add(cursor.getInt(0));
                titles_list.add(cursor.getString(1));
                notes_list.add(cursor.getString(2));
                remark_list.add(cursor.getString(3));
            

        

        // Relesing database object
        public void closeDatabase() 
            // close the database, always remember only close the database when it is opened
            db.close();
        
    

这是我的 MainNotes.java,noteslist 对我来说似乎是个错误。但我不知道如何更改我的代码。 .

public class MainNotes extends AppCompatActivity implements View.OnClickListener 

    private NotesCRUDManager nmanager;
    private Button create, clear, noteslist;
    private EditText title, note, remark;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_notes);

        create = (Button)findViewById(R.id.create);
        clear = (Button)findViewById(R.id.clear);
        noteslist = (Button)findViewById(R.id.create_shownotes);
        title = (EditText)findViewById(R.id.create_title_edittext);
        note = (EditText)findViewById(R.id.create_note_edittext);
        remark = (EditText)findViewById(R.id.create_remark_edittext);

        create.setOnClickListener(this);
        clear.setOnClickListener(this);
        noteslist.setOnClickListener(this);
    

    @Override
    public void onClick(View v) 
        if(v==create) 
            nmanager = new NotesCRUDManager(this);
            nmanager.InsertNote(title.getText().toString(), note.getText().toString(), remark.getText().toString());
            Toast.makeText(this, "Note Created", Toast.LENGTH_SHORT).show();
        

        else if (v==clear)
            // clear all text inside Edittext
            title.setText("");
            note.setText("");
            remark.setText("");
        

        else if (v==noteslist) 
            // start NotesList Activity
            Intent intent = new Intent(this, ShowNotesList.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(intent);
        
    

    @Override
    protected void onDestroy() 
        nmanager.closeDatabase();
        super.onDestroy();
    


【问题讨论】:

【参考方案1】:

如果用户不点击,nmanager 对象未初始化,导致崩溃。

改变这个:

@Override
protected void onDestroy() 
    nmanager.closeDatabase();
    super.onDestroy();

到这里:

@Override
protected void onDestroy() 
    if(nmanager != null)
        nmanager.closeDatabase();
    
    super.onDestroy();

【讨论】:

【参考方案2】:

notelist 好像是错误

不,阅读堆栈跟踪...

at plp.plpedia.developer.larriane.my_plpedia.MainNotes.onDestroy(MainNotes.java:60)

当 Activity 被销毁并且您没有点击创建按钮时会发生什么?

您的数据库引用为空!

移动

nmanager = new NotesCRUDManager(this);

进入 onCreate

此外,使用 SqliteOpenHelper 类可能会有所帮助

【讨论】:

以上是关于空对象引用上的closeDatabase()'的主要内容,如果未能解决你的问题,请参考以下文章

空对象引用上的 onActivityResult 数据

java.lang.NullPointerException:空对象引用上的 FloatingActionButton.setVisibility(int)'

空对象引用上的 void android.view.View.dispatchWindowVisibilityChanged(int)'

.getImage() 上的空对象引用 android [重复]

移动相机方法上的谷歌地图空对象引用[关闭]

空对象引用上的 TransitionSet ArrayList.size()