简体   繁体   中英

NullPointerException in ContextWrapper.openOrCreateDatabase when using SQLiteOpenHelper

I'm making a new android application that uses databases. I used similar code to create and copy database, but it's not working for some reason. I can't figure it out, help. LogCat:

07-03 21:38:54.260: E/AndroidRuntime(12172): FATAL EXCEPTION: main
07-03 21:38:54.260: E/AndroidRuntime(12172): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{lv.revopeng.guessthelocation/lv.revopeng.guessthelocation.LevelActivity}: java.lang.NullPointerException
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.os.Looper.loop(Looper.java:123)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.app.ActivityThread.main(ActivityThread.java:4627)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at java.lang.reflect.Method.invokeNative(Native Method)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at java.lang.reflect.Method.invoke(Method.java:521)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at dalvik.system.NativeStart.main(Native Method)
07-03 21:38:54.260: E/AndroidRuntime(12172): Caused by: java.lang.NullPointerException
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:112)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at lv.revopeng.guessthelocation.DataBaseHelper.open(DataBaseHelper.java:114)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at lv.revopeng.guessthelocation.DataBaseHelper.getLastId(DataBaseHelper.java:128)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at lv.revopeng.guessthelocation.LevelActivity.<init>(LevelActivity.java:31)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at java.lang.Class.newInstanceImpl(Native Method)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at java.lang.Class.newInstance(Class.java:1429)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
07-03 21:38:54.260: E/AndroidRuntime(12172):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
07-03 21:38:54.260: E/AndroidRuntime(12172):    ... 11 more

DataBaseHelper.java:

public class DataBaseHelper extends SQLiteOpenHelper {

    // The Android's default system path of your application database.
    private static String DB_PATH = "/data/data/lv.revopeng.guessthelocation/databases/";
    private static String DB_NAME = "GuessTheLocationTest.db";
    public static final String TABLE_NAME1 = "gtl_levels";

    public static final String WHATTODONOW_COLUMN_ID = "_id";
    public static final String WHATTODONOW_COLUMN_INFO = "levelInfo";
    public static final String WHATTODONOW_COLUMN_ANSWER = "levelAnswer";
    public static final String WHATTODONOW_COLUMN_IMAGE = "levelImage";
    public static final String WHATTODONOW_COLUMN_CLEARED = "levelCleared";
    private DataBaseHelper openHelper;
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    public DataBaseHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
    }

    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {
        } else {
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    private boolean checkDataBase() {

        SQLiteDatabase checkDB = null;

        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);

        } catch (SQLiteException e) {
        }
        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    private void copyDataBase() throws IOException {

        InputStream myInput = myContext.getAssets().open(DB_NAME);

        String outFileName = DB_PATH + DB_NAME;

        OutputStream myOutput = new FileOutputStream(outFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        myOutput.flush();
        myOutput.close();
        myInput.close();

    }

    public void openDataBase() throws SQLException {

        // Open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    }

    @Override
    public synchronized void close() {
        if (myDataBase != null)
            myDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase myDataBase, int oldVersion,
            int newVersion) {
    }

    public DataBaseHelper open() throws SQLException {
        openHelper = new DataBaseHelper(myContext);
        myDataBase = openHelper.getWritableDatabase();
        return this;
    }

    public void closee() {
        openHelper.close();
    }

    String[] columns = new String[] { WHATTODONOW_COLUMN_ID,
            WHATTODONOW_COLUMN_INFO, WHATTODONOW_COLUMN_ANSWER,
            WHATTODONOW_COLUMN_IMAGE, WHATTODONOW_COLUMN_CLEARED };

    public int getLastId() {
        int id = 0;
        open();
        final String MY_QUERY = "SELECT MAX(_id) AS _id FROM " + TABLE_NAME1;
        Cursor mCursor = myDataBase.rawQuery(MY_QUERY, null);
        try {
            if (mCursor.getCount() > 0) {
                mCursor.moveToFirst();
                id = mCursor.getInt(0);
                mCursor.close();
                close();
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
        }
        return id;

    }

On LevelActivity.java the createDataBase() method is called and on first DataBaseHelper use it gets the error.

EDIT: For me, it looks like getLastId is null, but it shouldn't be, so there are problem accessing the database. I looked at File Explorer, the database is there and info in it is correct.

Found my mistake. I called an function that gets data from database before creating the database..

  1. Remove open() method.

  2. Do not call getReadableDatabase(); and/or getWritableDatabase(); within DataBaseHelper.java, instead work directly with the database (ie, use execSQL() , query() , insert() , etc). Use those methods elsewhere as dataBaseHelper.getReadableDatabase(); , dataBaseHelper.getWritableDatabase(); .

  3. Remove DB_PATH and do not use one. You do not need to provide the path, the system will create and read the database from your packages databases folder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM