2013-07-20 2 views
2

Я создаю новое приложение для Android, которое использует базы данных. Я использовал аналогичный код для создания и копирования базы данных, но по какой-то причине он не работает. Я не могу понять, помогите. LogCat:NullPointerException в ContextWrapper.openOrCreateDatabase при использовании SQLiteOpenHelper

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; 

    } 

метод На LevelActivity.java CreateDatabase() вызывается и на первом DataBaseHelper использовать его получает ошибку.

EDIT: для меня это выглядит так: getLastId имеет значение NULL, но этого не должно быть, поэтому возникают проблемы с доступом к базе данных. Я посмотрел на File Explorer, база данных есть, и информация в нем верна.

+0

Похоже, возможно, что DatabaseHelper был создан с нулевым контекстом. –

ответ

1

Нашли ошибку. Я вызвал функцию, которая получает данные из базы данных до создания базы данных.

0
  1. Удалить open() метод.

  2. Не называйте getReadableDatabase(); и/или getWritableDatabase(); в DataBaseHelper.java, вместо того, чтобы работать непосредственно с базой данных (то есть, использовать execSQL(), query(), insert() и т.д.). Используйте эти методы в другом месте: dataBaseHelper.getReadableDatabase();, dataBaseHelper.getWritableDatabase();.

  3. Удалить DB_PATH и не использовать его. Вам не нужно указывать путь, система создаст и прочитает базу данных из папки баз данных пакетов.

+1

Но почему каждый работает отлично в моем другом приложении? – user1816780