Я возникли проблемы с обновления списка контактов для фрагмента, каждый раз, когда я пытаюсь вызвать метод, который обновляет список, я получаю эту ошибку:Android NullPointerException базы данных при открытии второй раз
01-11 17:55:48.215: W/System.err(25594): java.lang.NullPointerException
01-11 17:55:48.235: W/System.err(25594):at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
01-11 17:55:48.235: W/System.err(25594): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
01-11 17:55:48.235: W/System.err(25594): at com.Spit.pocketbook.DatabaseManager.<init>(DatabaseManager.java:48)
01-11 17:55:48.235: W/System.err(25594): at com.Spit.pocketbook.ContactsFragment.getContacts(ContactsFragment.java:105)
01-11 17:55:48.235: W/System.err(25594): at com.Spit.pocketbook.ContactsFragment.fillContactList(ContactsFragment.java:70)
01-11 17:55:48.235: W/System.err(25594): at com.Spit.pocketbook.SwipeActivity.onFinishCreateContactDailog(SwipeActivity.java:96)
01-11 17:55:48.235: W/System.err(25594): at com.Spit.pocketbook.ContactCreateDialog$PositiveButtonListener.onClick(ContactCreateDialog.java:129)
01-11 17:55:48.235: W/System.err(25594): at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
01-11 17:55:48.235: W/System.err(25594): at android.os.Handler.dispatchMessage(Handler.java:99)
01-11 17:55:48.235: W/System.err(25594): at android.os.Looper.loop(Looper.java:137)
01-11 17:55:48.235: W/System.err(25594): at android.app.ActivityThread.main(ActivityThread.java:4950)
01-11 17:55:48.235: W/System.err(25594): at java.lang.reflect.Method.invokeNative(Native Method)
01-11 17:55:48.235: W/System.err(25594): at java.lang.reflect.Method.invoke(Method.java:511)
01-11 17:55:48.245: W/System.err(25594): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
01-11 17:55:48.245: W/System.err(25594): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
01-11 17:55:48.245: W/System.err(25594): at dalvik.system.NativeStart.main(Native Method)
Так что это происходит каждый раз, когда я использую этот метод в ContactsFragment
private ArrayList<Contact> getContacts(){
DatabaseManager manager = new DatabaseManager(getActivity());
ArrayList<Contact> contacts = manager.getAllContacts();
manager.close();
return contacts;
}
, который создает новый DatabaseManager (который я создал, чтобы сделать тяжелую работу в базе данных и завернуть хорошо для остальной части моего приложения):
public DatabaseManager(Context context){
mDatabase = new DatabaseHelper(context).getWritableDatabase(); //Line 48 (where the error occurs)
mContext = context;
}
и вот getAllContacts()
метод для справки:
public ArrayList<Contact> getAllContacts(){
ArrayList<Contact> contacts = new ArrayList<Contact>();
//query the database for all the contacts
String[] projections = {ContactsTable._ID,
ContactsTable.COLUMN_CONTACT_NAME,
ContactsTable.COLUMN_LOOKUP_KEY,
ContactsTable.COLUMN_SCOPE};
Cursor C = mDatabase.query(ContactsTable.CONTACTS_TABLE_NAME, projections,
null, null, null, null, ContactsTable.COLUMN_CONTACT_NAME + " ASC");
//iterates through the results and adds them all to the ArrayList
while(C.moveToNext()){
Contact contact = new Contact(C.getLong(0),
C.getString(1),
C.getString(2),
C.getString(3));
contacts.add(contact);
}
C.close(); //save from memory leakage
return contacts;
}
Примечание: «M» переменные представляют собой глобальные переменные
Самое интересное во всем этом является то, что этот же метод (.getContacts()
) вызывается при создании ContactFragment, который также вызывает конструктор DatabaseManager таким же образом. В дополнение ко всему этому, когда мое приложение загружается, открывается ViewPager (SwipeActivity для тех, кто действительно читает журнал), который загружает два фрагмента. The ContactsFragment и другой SummaryFragment, который использует очень похожий метод для .getContact()
, чтобы получить другую информацию в базе данных. Но мое приложение работает хорошо, когда оно загружается. Вся информация извлекается и отображается очень хорошо. Только когда я попробую обновить его во второй раз в любом фрагменте жизни, я получу и ошибку. Единственное исправление, которое я нашел, это повернуть экран, который в основном сбрасывает и воссоздает все в Activity.
Поскольку он работает, когда я поворачиваю экран, это заставляет меня думать, что это проблема с тем фактом, что, хотя я закрыл базу данных, она как-то остается открытой, и именно поэтому я не могу назвать ее второй раз обновите списки. Если это проблема, я не знаю, как ее исправить, и буду признателен за любую помощь в этом, но опять же, это может не иметь никакого отношения к этому.
Вот мой призыв к manager.close()
который закрывает базу данных, что DatabaseManager открывается при его создании:
public void close(){
mDatabase.close();
}
Я боролся с этой проблемой в течение нескольких дней в настоящее время. Я провел некоторое исследование (без видимых результатов) и посмотрел на различные способы получения ошибки, но каждое исправление, которое я придумал, не имеет никакого эффекта.
Спасибо впереди времени для любого и всех советов/помощи,
Давид (Кос)
Извините, что знаю, что это не ответ, но я бы настоятельно рекомендовал рефакторинг этого кода. Вы делаете запрос базы данных в потоке пользовательского интерфейса, который является большим нет-нет. Вы также передаете активность, которая просто требует утечки памяти. Вы должны использовать API-интерфейсы Loader (мне нравится, когда мои Fragments реализуют интерфейс LoaderManager.LoaderCallbacks), который заботится не только о проблемах с потоками, но также позволяет открывать/закрывать базу данных, которая решит исключение, которое у вас есть. –
@Sam_D Я попробую поблагодарить вас. – Spit