Исключение исключения пустого указателя при открытии базы - PullRequest
0 голосов
/ 13 августа 2011

У меня странная ошибка в моем приложении. Когда после использования я оставляю его в фоновом режиме (для использования других приложений), а затем пытаюсь вернуться в свое приложение. Вызов для получения объекта DBAdapter завершается с ошибкой нулевого указателя. Вот эта трассировка стека

 ERROR/AndroidRuntime(21804): FATAL EXCEPTION: main
 ERROR/AndroidRuntime(21804): java.lang.RuntimeException: Unable to resume activity {com.newproject/com.newproject.ui.MainGalleryUI}: java.lang.NullPointerException
 ERROR/AndroidRuntime(21804):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2124)
 ERROR/AndroidRuntime(21804):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
 ERROR/AndroidRuntime(21804):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1672)
 ERROR/AndroidRuntime(21804):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
 ERROR/AndroidRuntime(21804):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
 ERROR/AndroidRuntime(21804):     at android.os.Handler.dispatchMessage(Handler.java:99)
 ERROR/AndroidRuntime(21804):     at android.os.Looper.loop(Looper.java:130)
 ERROR/AndroidRuntime(21804):     at android.app.ActivityThread.main(ActivityThread.java:3687)
 ERROR/AndroidRuntime(21804):     at java.lang.reflect.Method.invokeNative(Native Method)
 ERROR/AndroidRuntime(21804):     at java.lang.reflect.Method.invoke(Method.java:507)
 ERROR/AndroidRuntime(21804):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
 ERROR/AndroidRuntime(21804):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
 ERROR/AndroidRuntime(21804):     at dalvik.system.NativeStart.main(Native Method)
 ERROR/AndroidRuntime(21804): Caused by: java.lang.NullPointerException
 ERROR/AndroidRuntime(21804):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
 ERROR/AndroidRuntime(21804):     at com.newproject.services.DBAdapter.open(DBAdapter.java:98)
 ERROR/AndroidRuntime(21804):     at com.newproject.services.DBAdapter.getInstance(DBAdapter.java:85)
 ERROR/AndroidRuntime(21804):     at com.newproject.ui.MainUI.onResume(MainUI.java:51)
 ERROR/AndroidRuntime(21804):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)
 ERROR/AndroidRuntime(21804):     at android.app.Activity.performResume(Activity.java:3832)
 ERROR/AndroidRuntime(21804):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2114)
 ERROR/AndroidRuntime(21804):     ... 12 more
08-13 18:32:02.660: ERROR/(477): Dumpstate > /data/log/dumpstate_app_error

И некоторые фрагменты кода: У MainUI.java onResume ():

  DBAdapter db= DBAdapter.getInstance();

В DBAdapter:

private DatabaseHelper mDbHelper;
public static DBAdapter instance;
public static DBAdapter getInstance(){
    if (instance==null){
        instance=new DBAdapter();
        instance.open();
    }
    return instance;
}

public DBAdapter(){
}

private synchronized DBAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper();
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

И самое редкое, что, изучая исходный код, метод

  public synchronized SQLiteDatabase getWritableDatabase() {
    if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
        return mDatabase;  // The database is already open for business
    }

    if (mIsInitializing) {
        throw new IllegalStateException("getWritableDatabase called recursively");
    }

    // If we have a read-only database open, someone could be using it
    // (though they shouldn't), which would cause a lock to be held on
    // the file, and our attempts to open the database read-write would
    // fail waiting for the file lock.  To prevent that, we acquire the
    // lock on the read-only database, which shuts out other users.

    boolean success = false;
    SQLiteDatabase db = null;
    if (mDatabase != null) mDatabase.lock();
    try {
        mIsInitializing = true;
        if (mName == null) {
            db = SQLiteDatabase.create(null);
        } else {
            db = mContext.openOrCreateDatabase(mName, 0, mFactory);
        }

        int version = db.getVersion();
        if (version != mNewVersion) {
            db.beginTransaction();
            try {
                if (version == 0) {
                    onCreate(db);
                } else {
                    onUpgrade(db, version, mNewVersion);
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }

        onOpen(db);
        success = true;
        return db;
    } finally {
        mIsInitializing = false;
        if (success) {
            if (mDatabase != null) {
                try { mDatabase.close(); } catch (Exception e) { }
                mDatabase.unlock();
            }
            mDatabase = db;
        } else {
            if (mDatabase != null) mDatabase.unlock();
            if (db != null) db.close();
        }
    }
}

Строка 118 (по крайней мере, в моем исходном коде соответствует

success = true;

Так что бессмысленно исключение для нулевого указателя

Заранее спасибо

Редактировать:

Нашел проблему, спасибо. Вот оно

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper() {
        super(Manager.appcontext, DB_NAME, null,DB_VERSION);
    }

Я использовал статическую переменную для сохранения контекста приложения, но после того, как ОС была убита, переменная имеет значение null

Ответы [ 2 ]

1 голос
/ 13 августа 2011

Что в DatabaseHelper?Вам нужно Context для инициализации SQLiteOpenHelper, так что это, скорее всего, ноль.

0 голосов
/ 13 августа 2011

Вы работаете в Eclipse?

Если ошибки не совпадают с номерами строк, я обновил бы код и очистил приложение.

Чтобы обновить, щелкните правой кнопкой мыши напроект и выберите обновить.

Очистка доступна в главном меню Project.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...