完了したらデータベースを閉じようとしていますか?そうしようとした場合 :
public Cursor query() {
SQLiteDatabase db = null;
try {
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.query(Cfg.table_name, new String[] {"*"}, null, null, null, null, null);
return c;
}
catch(Exception exp) {
}finally{
try{if(null != db){ db.close(); db = null;}}catch(Exception e){}
}
return null;
}
適切に毎回デシベルを閉じる必要があること。なぜそれが閉鎖されていないのだろうと思っているなら、私はExceptionが言っているものを捜査するだろう。
ところで、私は "new String [] {" * "}"をnullに置き換えます。 http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
更新:これで問題は分かりました。あなたは少しクラスを再構成する必要があるかもしれません。
TLDR:私にとって理想的なのは、2つのクラスになります。 1つは、DBのオープンを支援するためのものです。次にSQLiteDatabaseオブジェクトをプロパティとして保持します。このクラスを作成するとすぐに接続を開いてDBオブジェクトを初期化することができます(またはデータベースを開くためのメソッドの使用を作成する)。すべてのメソッドは、dbオブジェクトのみをSCUDに使用します。その後、すべてのdbオブジェクトのクローズまたは分解は、メソッドに置くことも、onDestroyをオーバーライドすることもできます。 以下の例は、これを惜しまない時間があればよいチュートリアルですhttp://www.vogella.de/articles/AndroidSQLite/article.html。
最初のものはDBOpenHelperです。このクラスの目的は、テーブルを管理し、データベースを開いて変更するのに役立ちます。
package com.mondial.th.rsa.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* DBOpenHelper helps opening database and managing database's upgrade or creation.
* @author Poohdish Rattanavijai
*
*/
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String TAG = DBOpenHelper.class.getSimpleName();
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "rsa_db";
public DBOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public DBOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase database) {
Log.d(TAG, "DBOpenHelper.onCreate");
// Create table goes here.
}
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
// Drop and recreate table goes here.
}
}
第二のクラスは、前に示したDBOpenHelperを使用することにより、あなたのためのすべてのクエリを処理します。
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.mondial.th.rsa.vo.ProfileVO;
/**
* Database adapter for managing Profile table
* @author Poohdish Rattanavijai
*
*/
public class ProfileDBAdapter {
private static final String TAG = ProfileDBAdapter.class.getName();
private Context context;
private SQLiteDatabase db;
private DBOpenHelper dbHelper;
public ProfileDBAdapter(Context context){
this.context = context;
}
/**
* Open writable database.
* @return writable SQLDatabase
* @throws SQLException
*/
public ProfileDBAdapter open() throws SQLException{
Log.d(TAG, "Open ProfileDBAdapter");
dbHelper = new DBOpenHelper(context);
db = dbHelper.getWritableDatabase();
return this;
}
/**
* Close database; Exception omitted
*/
public void close(){
try {
dbHelper.close();
} catch (Exception e) {
//e.printStackTrace();
}
}
/**
* Creating new record in profile table with given VO.
* @param profile VO representing data in the new record.
* @return the row ID of the newly inserted row, or -1 if an error occurred.
*/
public long createProfile(ProfileVO profile){
ContentValues values = createContentValues(profile);
return db.insert(ProfileVO.TABLE_NAME, null, values);
}
/**
* Updating record in profile table with given VO by using ID column.
* @param profile VO representing new data to updated.
* @return the number of rows affected .
*/
public boolean updateProfile(ProfileVO profile){
ContentValues values = createContentValues(profile);
return db.update(ProfileVO.TABLE_NAME, values, ProfileVO.COLUMN_ID + "=" + profile.getId(), null) > 0;
}
/**
* Deleting a row representing given VO off profile table by using ID column.
* @param profile
* @return
*/
public boolean deleteProfile(ProfileVO profile){
return deleteProfile(profile.getId());
}
/**
* Deleting a row off profile table with given ID column.
* @param profile
* @return
*/
public boolean deleteProfile(long rowId){
return db.delete(ProfileVO.TABLE_NAME, ProfileVO.COLUMN_ID + "=" + rowId, null) > 0;
}
/**
* open cursor representing every records in profile table.
* @return Cursor representing every records in profile table.
*/
public Cursor fetchAllProfiles(){
return db.query(ProfileVO.TABLE_NAME, null, null, null, null, null, null);
}
/**
* open cursor representing a row in profile table with given ID.
* @return Cursor representing a row in profile table with given ID.
*/
public Cursor fetchProfile(long rowId){
Cursor mCursor = db.query(true, ProfileVO.TABLE_NAME, null, ProfileVO.COLUMN_ID + "=" + rowId
, null, null, null, null, null);
if(null != mCursor){
mCursor.moveToFirst();
}
return mCursor;
}
/**
* This class translate given VO into ContentValues for ContentResolver to parse data and talk to the database.
* @param profile VO
* @return ContentsValues containing given VO's data except ID.
*/
private ContentValues createContentValues(ProfileVO profile){
ContentValues values = new ContentValues();
values.put(ProfileVO.COLUMN_DOB, profile.getDob());
values.put(ProfileVO.COLUMN_FIRSTNAME, profile.getFirstname());
values.put(ProfileVO.COLUMN_LASTNAME, profile.getLastname());
return values;
}
}
次に、DAOとして機能する完全なクラスが1つあります。上記の例では、使用方法は次のようになります。
ProfileDBAdapter dbHelper = new ProfileDBAdapter(context);
dbHelper.open();
cursor = dbHelper.fetchAllProfiles();
if(cursor.getCount() > 0){
//TODO Data exists, do stuff.
}
try {
if(null != cursor && !cursor.isClosed()){
cursor.close();
}
} catch (Exception e) {
e.printStackTrace();
}
if(null != dbHelper){
dbHelper.close();
dbHelper = null;
}
ありがとうございますが、dbを閉じた後にカーソルが無効になる問題があります。 – Dagang
私は答えを更新しました。それはちょっと長く、巻いていますが、それはあなたの問題を解決するのに役立ちます。 – RobGThai
あなたの答えをありがとう!あなたのソリューションは、ユーザーがdbHelperオブジェクトを取得できるときに問題を解決します。しかし、私のケースでは、クエリーがコンテンツプロバイダー上にあるため、ユーザーはdbHelperオブジェクトを取得できません。だから、私はユーザーがデータベースを閉じることを期待することはできません。 – Dagang