尝试从DataBase加载数据到android中的ListView

时间:2015-12-23 00:16:37

标签: java android nullpointerexception

我试图从sqlite数据库中获取数据并将其加载到列表视图中但是我收到此错误

12-23 02:04:01.751 3296-3296/com.chaos.todolist E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.chaos.todolist, PID: 3296
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.chaos.todolist/com.chaos.todolist.show}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String)' on a null object reference
at com.chaos.todolist.DataBase.getTasks(DataBase.java:28)
at com.chaos.todolist.show.LoadDataFromDataBaseToListView(show.java:30)
at com.chaos.todolist.show.onCreate(show.java:25)
at android.app.Activity.performCreate(Activity.java:6289)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758) 
at android.app.ActivityThread.access$900(ActivityThread.java:177) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:5942) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)at com.android.in ternal.os.ZygoteInit.main(ZygoteInit.java:1195)

这是数据库类函数,我还有另一个帮助程序..

package com.chaos.todolist;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class DataBase {

    private SQLiteDatabase mDatabase;
    private DB_Helper TODOHelper;

    public DataBase(Context context) {
        TODOHelper = new DB_Helper(context);
    }

    public void open() {
        mDatabase = TODOHelper.getWritableDatabase();
    }

    public void close() {
        if (mDatabase != null) {
            mDatabase.close();
        }
    }
    public Cursor getTasks() {
        String[] col = {TODOHelper.COLUMN_ID, TODOHelper.COLUMN_NAME };
        Cursor cursor = mDatabase.query(
                TODOHelper.TABLE_TASKS, // table name
                col , // column names
                null, // where clause
                null, // where params
                null, // groupby
                null, // having
                TODOHelper.COLUMN_NAME // orderby
        );
        return cursor;
    }

    public Cursor getTasksById(int id) {
        String[] columns = {TODOHelper.COLUMN_NAME, TODOHelper.COLUMN_DATE,
                TODOHelper.COLUMN_ADDRESS};

        return mDatabase.query(
                DB_Helper.TABLE_TASKS, // table name
                columns, // column names
                DB_Helper.COLUMN_ID + " = " + id, // where clause // id param. could be here or appended as it is ^
                null, // where params
                null, // groupby
                null, // having
                null // orderby
        );
    }

    public void deleteTaskById(int id) {
        open();
        mDatabase.delete(
                DB_Helper.TABLE_TASKS, // table name
                DB_Helper.COLUMN_ID +"="+ id, // where clause
                null // where params
        );
        close();
    }

    public void insertTask(String name, String date, String address) {
        mDatabase.beginTransaction();
        try {
            ContentValues newTask = new ContentValues();
            newTask.put(DB_Helper.COLUMN_NAME, name);
            newTask.put(DB_Helper.COLUMN_DATE, date);
            newTask.put(DB_Helper.COLUMN_ADDRESS, address);
            mDatabase.insert(DB_Helper.TABLE_TASKS, null, newTask);
            mDatabase.setTransactionSuccessful();
        }
        finally {
            mDatabase.endTransaction();
        }
    }

    public void updateTask(int rowId, String name, String date, String address) {
        ContentValues editTask = new ContentValues();
        editTask.put(DB_Helper.COLUMN_NAME, name);
        editTask.put(DB_Helper.COLUMN_DATE, date);
        editTask.put(DB_Helper.COLUMN_ADDRESS, address);

        mDatabase.update(
                DB_Helper.TABLE_TASKS, // table name
                editTask, // values
                DB_Helper.COLUMN_ID + " = " + rowId, // where clause
                null // where params
        );

    }
}

这是我应该使用加载数据的函数的类 show.java

package com.chaos.todolist;

import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class show extends AppCompatActivity {
    ListView listView;
    DataBase db;
    TextView empty;
    Cursor result;
    ArrayAdapter adapter;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.show);
        listView=( ListView) findViewById(R.id.listView1);
        db=new DataBase(show.this);
        empty = (TextView) findViewById(android.R.id.empty);
        Log.d("show", "is going to load database");
        LoadDataFromDataBaseToListView();
        listView.setEmptyView(empty);
    }

    public void LoadDataFromDataBaseToListView() {
        result=db.getTasks();
        Log.d("show","it got tasks");
        if (result != null && result.getCount() > 0) {
            Log.d("load data", "Load Data From DataBase To ListView has started");
            db.open();
            int i = 0;
            String[] names = new String[result.getCount()];
            int[] ids = new int[result.getCount()];
            try {
                Log.d("load data","in thr try");
                if (result.moveToFirst()) {
                    int index_id = result.getColumnIndex(DB_Helper.COLUMN_ID);
                    int index_name = result.getColumnIndex(DB_Helper.COLUMN_NAME);
                    Log.d("load data", "got the index");
                    do {
                        ids[i] = result.getInt(index_id);
                        String ss = result.getString(index_name);
                        names[i] = ss;
                        ++i;
                    } while (result.moveToNext());

                    db.close();
                    Log.d("load data", "clossed connection to database");
                    adapter = new ArrayAdapter<String>(
                            getApplicationContext(),
                            R.layout.taskitem,R.id.Task_name,
                            names);
                    listView.setAdapter(adapter);
                    Log.d("load data", "try finished");
                }
            } catch (Exception e) {
                Log.d("load data", "in catch");
                Toast.makeText(getApplicationContext(), e.getMessage(),
                        Toast.LENGTH_LONG).show();
            }
            Log.d("load data", "finished if");
        } else {
            Log.d("load data", "in else");
            Toast.makeText(this, "is null", Toast.LENGTH_LONG).show();
        }
    }

    protected void onResume() {
        super.onResume();

    }
    protected  void onPause()
    {
        super.onPause();
    }
}

2 个答案:

答案 0 :(得分:3)

要添加到上面的海报,如果您担心保护,您可能希望将open方法设为私有或受保护:

protected void open()
{
    mDatabase = TODOHelper.getWritableDatabase();
}

然后将构造函数更改为:

public DataBase(Context context) {
    TODOHelper = new DB_Helper(context);
    open();
}

这可能会节省一些努力。

答案 1 :(得分:1)

您必须先打开数据库,然后才能对其进行查询。这是您更新的onCreate

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.show);
    listView=( ListView) findViewById(R.id.listView1);
    db=new DataBase(show.this);
    db.open();
    empty = (TextView) findViewById(android.R.id.empty);
    Log.d("show", "is going to load database");
    LoadDataFromDataBaseToListView();
    listView.setEmptyView(empty);
}

如果您在调用getTasks方法之前未打开此方法,则此方法会尝试拨打仍为mDatabase.query的{​​{1}}。