saya akan tetap membukanya sepanjang waktu, dan menutupnya dalam beberapa metode siklus hidup seperti onStop
atau onDestroy
. dengan cara itu, Anda dapat dengan mudah memeriksa apakah database sudah digunakan dengan memanggil isDbLockedByCurrentThread
atau isDbLockedByOtherThreads
pada satu SQLiteDatabase
objek setiap kali sebelum Anda menggunakannya. ini akan mencegah beberapa manipulasi ke database dan menyimpan aplikasi Anda dari potensi crash
jadi di singleton Anda, Anda mungkin memiliki metode seperti ini untuk mendapatkan SQLiteOpenHelper
objek tunggal Anda :
private SQLiteDatabase db;
private MyDBOpenHelper mySingletonHelperField;
public MyDBOpenHelper getDbHelper() {
db = mySingletonHelperField.getDatabase();//returns the already created database object in my MyDBOpenHelper class(which extends `SQLiteOpenHelper`)
while(db.isDbLockedByCurrentThread() || db.isDbLockedByOtherThreads()) {
//db is locked, keep looping
}
return mySingletonHelperField;
}
jadi setiap kali Anda ingin menggunakan objek pembantu terbuka, panggil metode pengambil ini (pastikan itu berulir)
Metode lain di tunggal Anda mungkin (dipanggil SETIAP KALI sebelum Anda mencoba memanggil pengambil di atas):
public void setDbHelper(MyDBOpenHelper mySingletonHelperField) {
if(null == this.mySingletonHelperField) {
this.mySingletonHelperField = mySingletonHelperField;
this.mySingletonHelperField.setDb(this.mySingletonHelperField.getWritableDatabase());//creates and sets the database object in the MyDBOpenHelper class
}
}
Anda mungkin ingin menutup database di singleton juga:
public void finalize() throws Throwable {
if(null != mySingletonHelperField)
mySingletonHelperField.close();
if(null != db)
db.close();
super.finalize();
}
jika pengguna aplikasi Anda memiliki kemampuan untuk membuat banyak interaksi database dengan sangat cepat, Anda harus menggunakan sesuatu seperti yang telah saya tunjukkan di atas. tetapi jika ada interaksi database minimal, saya tidak akan mengkhawatirkannya, dan cukup buat dan tutup database setiap saat.
Sampai sekarang tidak perlu memeriksa apakah database dikunci oleh thread lain. Saat Anda menggunakan SQLiteOpenHelper tunggal di setiap utas, Anda aman. Dari
isDbLockedByCurrentThread
dokumentasi:isDbLockedByOtherThreads
tidak digunakan lagi sejak API Level 16.sumber
Mengenai pertanyaan:
Kita harus membagi 'membuka DB', 'membuka koneksi'. SQLiteOpenHelper.getWritableDatabase () memberikan DB terbuka. Tetapi kami tidak harus mengontrol koneksi karena dilakukan secara internal.
Ya itu. Koneksi tidak hang jika transaksi ditutup dengan benar. Perhatikan bahwa DB Anda juga akan ditutup secara otomatis jika GC menyelesaikannya.
Menutup instance SQLiteDatabase tidak memberikan hasil yang luar biasa kecuali menutup koneksi tetapi ini adalah hal yang buruk bagi developer jika ada beberapa koneksi saat ini. Selain itu, setelah SQLiteDatabase.close (), SQLiteOpenHelper.getWritableDatabase () akan mengembalikan instance baru.
Tidak, tidak ada. Perhatikan juga bahwa menutup DB pada momen dan utas yang tidak terkait misalnya di Activity.onStop () mungkin menutup koneksi aktif dan membiarkan data dalam keadaan tidak konsisten.
sumber
Android 8.1 memiliki
SQLiteOpenHelper.setIdleConnectionTimeout(long)
metode yang:https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#setIdleConnectionTimeout(long)
sumber
Dari perspektif kinerja, cara yang optimal adalah dengan menyimpan satu contoh SQLiteOpenHelper di tingkat aplikasi. Membuka database bisa mahal dan merupakan operasi pemblokiran, jadi tidak boleh dilakukan pada thread utama dan / atau dalam metode siklus hidup aktivitas.
Metode setIdleConnectionTimeout () (diperkenalkan di Android 8.1) bisa digunakan untuk mengosongkan RAM saat database tidak digunakan. Jika idle timeout diatur, koneksi database akan ditutup setelah periode tidak aktif, yaitu ketika database tidak diakses. Koneksi akan dibuka kembali secara transparan ke aplikasi, saat kueri baru dijalankan.
Selain itu, aplikasi bisa memanggil releaseMemory () saat masuk ke latar belakang atau mendeteksi tekanan memori, misalnya di onTrimMemory ()
sumber
Anda juga dapat menggunakan ContentProvider. Ini akan melakukan hal ini untuk Anda.
sumber
Buat konteks Aplikasi Anda sendiri, lalu buka dan tutup database dari sana. Objek itu juga memiliki metode OnTerminate () yang bisa Anda gunakan untuk menutup koneksi. Saya belum mencobanya tetapi tampaknya pendekatan yang lebih baik.
@binnyb: Saya tidak suka menggunakan finalize () untuk menutup koneksi. Mungkin berhasil, tetapi dari apa yang saya pahami menulis kode dalam metode Java finalize () adalah ide yang buruk.
sumber
onTerminate
tidak akan dipanggil dalam lingkungan produksi - developer.android.com/reference/android/app/…