SQLite getReadableDatabase() returns NULL - android

I'm using Android's SQLite to create a database of levels, based on some files. I first create a SQLiteOpenHelper, and on it I call getReadableDatabase() or getWritableDatabase() so the onCreate() method is called and my DB will be created:
#Override //Main Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper = new DbOpenHelper(this);
database = dbHelper.getWritableDatabase(); //is a field
-
public DbOpenHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
Log.d("CREATING CLASSS", "OSDIFJE*(#");
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_TABLE_CREATE);
loadLevelData();
}
// Load data into the database on creation
private void loadLevelData() {
Log.d("DbOpenHelper", "Loading Level Data");
AssetManager mgr = MenuActi ~~snip~~
Log.d("dataaosdifj",MenuActivity.database.toString()); //NullPointerException!
MenuActivity.database.insert(DB_TABLE_NAME, null, info);
}
i Also tried calling getWritableDatabase() inside the loadLevelData() method, same results.
I saw this is quite a common problem, however most threads about it don't have any solution!
Please :'(

Why are accessing an instance variable from an activity from inside your open helper? If I understand your code correctly, your loadLevelData() method is a method of your open helper. Instead of what you have, why not this:
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_TABLE_CREATE);
loadLevelData(db);
}
// Load data into the database on creation
private void loadLevelData(SQLiteDatabase db) {
...
db.insert(DB_TABLE_NAME, null, info);
}
The root of your problem is that the database instance variable in your activity isn't assigned by the time you access it down in your DbOpenHelper... you're still in the call that's creating the database -- which happens to be dbHelper.getWritableDatabase() -- and the result hasn't returned for the assignment.

Related

Android - try with resources just for creating database tables

In Android I have this part of code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(!prefs.getBoolean("firstTime", false)) {
new DatabaseHelper(this);
} }
Lint is now saying 'DatabaseHelper' used without 'try'-with-resources statement
In DatabaseHelper class I have this:
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 2);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "blabla");
}
So why do I need try with resources? Is it really needed here and how to do it in my case?
I tried something like:
try (DatabaseHelper myDb = new DatabaseHelper(this)){
} catch(IOException e) {
}
But I don't know what to put inside try statement as it is just creating the database tables and nothing else.
Strange is, if I define outside of onCreate DatabaseHelper myDb; and then inside onCreate I will have:
myDb = new DatabaseHelper(this);
then it is not complaining.
Why should I assign it to myDb variable, why it is complaining when I use the same without variable as new DatabaseHelper(this) ?
Is it really needed here...?
Yes, insofar as SQLiteOpenHelper extends AutoCloseable, and you seem to be hitting a Lint complaint about not closing it.
But I don't know what to put inside try statement as it is just creating the database tables and nothing else.
First, it is not creating database tables. That will not occur until you do something with the DatabaseHelper, such as call getWriteableDatabase().
Second, an AutoCloseable will have a close() method that satisfies the concern.
If your objective purely is to get rid of the Lint complaint, use:
try (DatabaseHelper myDb = new DatabaseHelper(this)){
myDb.close();
} catch(IOException e) {
}
You will need to do something else beyond close(), such as getReadableDatabase(), to get the tables to be created.

no database on my android phone

I am attempting to create a database in my Android app. It has worked, but when I restart the emulator I receive an error that indicates that my table does not exist. I have found that my "OnCreate" is not started and there is no directory on my sd card of my app? Can you help me find my mistake?
My code is:
public DatabaseVerwerker(Context context) {
super(context, database_naam, null, database_version);
}
public void onCreate(SQLiteDatabase db)
db.execSQL("CREATE TABLE IF NOT EXISTS variabel (key TEXT, value TEXT);");
)
And will the database still exists after close and open the app?
Greatings,
I hope it's my last post of android. it get's to mutch
Make sure your database has been created before you do your operation on database. The better way to create a database only used by your application is using openOrCreateDatabase. Here is the example.
CursorFactory cursorFactory = new CursorFactory() {
#Override
public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery,
String editTable, SQLiteQuery query) {
return null;
}
};
openOrCreateDatabase(DBNAME, MODE_PRIVATE, cursorFactory, new DatabaseErrorHandler() {
#Override
public void onCorruption(SQLiteDatabase dbObj) {
}
})
Thanks it works again. i must build the onUpdate function and trigger it.

SQLite - getDatabase called recursively

Here is my code:
public class DBHelper extends SQLiteOpenHelper {
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("sql-query");
try {
//db = getWritableDatabase();
fillAllDB(db);
} catch (JSONException e) {
e.printStackTrace();
}
}
// some code
}
fillAllDB(db); method adds a record to the table, but I can't use db = getWritableDatabase(); before method call - this is causing the looping. What to do in this case?
OnCreate method gives you writable database only, so no need to get the writable database, when you call the writable/readable database, sqlite framework checks whether database exist or not, if not then it will call the onCreate method, that why this is recursive, you should not call getWritable/getReadable database in onCreate/onUpgrade method of the SqliteOpenHelper class
Use the SQLiteDatabase db argument passed to your onCreate() method as the database to call your operations on.
getWritableDatabase() and getReadableDatabase() will invoke your onCreate() in case the database file did not exist, and calling get...Database() recursively while the previous call is still being processed causes this exception.
Also, catching exceptions in onCreate() is not a good idea. If there's a problem, the onCreate() method should not return normally - that tells the framework that the database setup was successful.

how to show listview context by database

i have a listview in my project that links to database and shows its context from database but my problem is whenever my application runs it records goes twice (ex.2records first run, 4records with same context,...) and i do not know that wat is problem
this is my database class:
new File(DIR_DATABASE).mkdirs();
dataBase = SQLiteDatabase.openOrCreateDatabase(DIR_DATABASE + "/information.sqlite", null);
dataBase.execSQL("CREATE TABLE IF NOT EXISTS information (" +
"information_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE ," +
"information_title TEXT)");
dataBase.execSQL("INSERT INTO information (information_title) VALUES ('قسمت اول')");
dataBase.execSQL("INSERT INTO information (information_title) VALUES ('قسمت دوم')");
and its my main class that shows listview:
ListView lstC findViewById(R.id.lstContent);
adapter = new AdapterNote(title);
lstContent.setAdapter(adapter);
readFromDataBase();
adapter.notifyDataSetChanged();
}
private void readFromDataBase() {
Cursor cursor = G.dataBase.rawQuery("SELECT * FROM information", null);
while (cursor.moveToNext()) {
StructNote detail = new StructNote();
detail.title = cursor.getString(cursor.getColumnIndex("information_title"));
title.add(detail);
}
cursor.close();
adapter.notifyDataSetChanged();
}
You need to understand SQLiteOpenHelper for this. This is workflow issue, so it would be better you should go through some tutorial. This is a nice tutorial where you can learn the concept.
In very short i am listing few points that may be useful for you:
In your application you create a subclass of the SQLiteOpenHelper class.SQLiteOpenHelper is a helper class to manage database creation and version management. In subclass override, onCreate() and onUpgrade().
public class MySQLiteHelper extends SQLiteOpenHelper {
public void onCreate(SQLiteDatabase database) {
// create database command.
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// upgrade database command here.
}
}
Create a DAO class that will manage the interaction with the database. Your CRUD methods will go here. See DAO pattern for details. This class will centralize the access to database, hence your activity, fragment will interact with this class to perform operation. Direct access to database won't be allowed.
public class ModelDataSource {
// needed to perform operation on database
private SQLiteDatabase database;
//needed to retrieve database object
private MySQLiteHelper dbHelper;
public boolean insertModel(Model model) {
// perform insert operation on database
}
}
In your activity, you can interact with DAO to perform some action.
public class YourActivity extends Activity {
private ModelDataSource datasource;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
datasource = new ModelDataSource(this);
datasource.open();
boolean insertion_status = datasource.insert(modelobject);
}
}

SQLite IllegalStateException: where do I close the database?

I'm getting two contradicting Exceptions when creating and populating my new SQLiteDatabase in Android. In short my code:
SQLiteOpenHelper extending class:
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_TABLE_CREATE);
loadLevelData(db); //puts data in the database
//db.close(); <<< ?
}
In my activity class I instantiate this class (in onCreate()), and call getWritableDatabase():
dbHelper = new DbOpenHelper(getApplicationContext());
database = dbHelper.getWritableDatabase();
Now if I don't call db.close() after populating the database, like above, I get
android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
However if I DO close it, I get the following exception:
java.lang.IllegalStateException: database not open
on getWritableDatabase().
This really confuses me, so could anyone help me with what's wrong?
You are not expected to close the database in the DatabaseHelper class. However you need to close it every time you open it calling getWritableDatabase:
dbHelper = new DbOpenHelper(getApplicationContext());
database = dbHelper.getWritableDatabase();
//... do something with database
database.close();
You are closing your database at the wrong time.
I typically keep the database around like this:
public class MyActivity extends Activity {
SQLiteDatabase writeableDb;
// ...
// Code
// ...
public void onStart(){
super.onCreate(savedState);
// Do stuff, get your helper, etc
writeableDb = helper.getWriteableDatabase();
}
public void onStop(){
writeableDb.close();
super.onStop();
}
}
Alternatively, wrap all your code working with that db connection in a try/finally block
db = helper.getWriteableDatabase();
try { // ... do stuff ... }
finally { db.close(); }
Note: All of the opening/closing should be done in the Activity working with the database, not the open helper.

Categories

Resources