passing context from non-activity - android

i yet really grasp this whole context thing we found a lot in android programming. so i tried creating a function to drop all my tables, and here's a my partial code:
public class DBAdapter {
private static class DbHelper extends SQLiteOpenHelper {
private boolean databaseCreated = false;
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void deleteTables(){
Log.d("DBAdapter","dlm drop tables pre");
this.sqlDatabase.execSQL("DROP TABLE IF EXISTS ["+TABLE_TV+"];");
this.sqlDatabase.execSQL("DROP TABLE IF EXISTS ["+TABLE_CAMERA+"];");
this.sqlDatabase.execSQL("DROP TABLE IF EXISTS ["+TABLE_GPS+"];");
}
}
}
and the part where i'm going to call the function deleteTables
public class UpdateDatabase {
public void updateTable(String table,JSONObject jsonObject){
DBAdapter db = new DBAdapter(this);
db.deleteTables();
}
}
but of course it will return an error, since DBAdapter expects a context. public class UpdateDatabase is not an activity class. Calling DbAdapter db = new DBAdapter(this) from activity class will work just find. So how do I find any fix for this problem?
thanks

You can add a constructor to UpdateDatabase that takes a Context and stores it so that it is available to be used by updateTable. Something like this:
public class UpdateDatabase {
private final Context mContext;
public UpdateDatabase(Context context){
mContext = context;
}
public void updateTable(String table,JSONObject jsonObject){
DBAdapter db = new DBAdapter(mContext);
db.deleteTables();
}
}
Now, whenever you do new UpdateDatabase() you will need to do new UpdateDatabase(..context..) instead. If you are doing this from an Activity, then you can do new UpdateDatabase(this).

hi look this code..
public class DbManager
{
// the Activity or Application that is creating an object from this class.
Context context;
CustomSQLiteOpenHelper helper;
// a reference to the database used by this application/object
protected SQLiteDatabase db;
private static DbManager INSTANCE;
// These constants are specific to the database.
protected final String DB_NAME = "yourDB";
protected final int DB_VERSION = 1;
public DbManager(Context context)
{
this.context = context;
// create or open the database
helper = new CustomSQLiteOpenHelper(context);
this.db = helper.getWritableDatabase();
}
public static DbManager getInstance(Context context){
if(INSTANCE == null)INSTANCE = new DbManager(context);
return INSTANCE;
}
public void db_Close()
{
if(helper!=null){
helper.close();
}
this.db.close();
}
private class CustomSQLiteOpenHelper extends SQLiteOpenHelper
{
public CustomSQLiteOpenHelper(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
// This string is used to create the database.
// execute the query string to the database.
//db.execSQL(newTableQueryString);
Log.i("DataBaseManager", "Create Table");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// NOTHING TO DO HERE. THIS IS THE ORIGINAL DATABASE VERSION.
// OTHERWISE, YOU WOULD SPECIFIY HOW TO UPGRADE THE DATABASE.
}
}
}
// Inherit the DbManager Class
public class DataCollection extends DbManager {
public DataCollection(Context context){
super(context);
}
public void deleteTable(String TABLE_NAME){
try {db.execSQL("DROP TABLE "+TABLE_NAME);}//.delete(TABLE_NAME, null, null);}
catch (Exception e){
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
}

Related

Deleting SQLite Database before opening a new database

I'm having serious problems trying to get SQLite working with Android. I keep getting errors such as "unknown error (code 14): Could not open database".
One method I found that gets rid of this error temporarily is to delete the database and then create one. There mightn't even be a database but calling deleteDatabase() seems to fix the problem.
File DB_PATH = getApplicationContext().getDatabasePath("test.db");
DB_PATH.mkdirs();
DatabaseHelper dbh = DatabaseHelper.getHelper(this);
SQLiteDatabase db;
SQLiteDatabase.deleteDatabase(DB_PATH);
db = dbh.getWritableDatabase();
DatabaseHelper
public DatabaseHelper(Context ctx) {
super(ctx, ctx.getApplicationContext().getDatabasePath("test.db").getPath(), null, 10);
this.context = ctx;
}
public static synchronized DatabaseHelper getHelper(Context context) {
if (instance == null) {
instance = new DatabaseHelper(context);
}
return instance;
}
What I'm wondering is why would deleting the database make a difference and any advice in general would be appreciated?
Try using this template
public class MyDBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "myDatabase.db";
private static final int SCHEMA = 1;
private static volatile MyDBHelper sInstance;
private MyDBHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA);
}
public static MyDBHelper getInstance(Context context) {
if (sInstance == null) {
synchronized (MyDBHelper.class) {
if (sInstance == null) {
sInstance = new MyDBHelper(context.getApplicationContext());
}
}
}
return sInstance;
}
#Override
public void onCreate(SQLiteDatabase db) {
// create your tables here
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// handle db upgrade or leave blank
}
}

SQLite Connection leaked although everything closed

I found many stuff like close the connection and close the cursor, but I do all this stuff. Still the SQLite connection leaks and I get a warning like this:
A SQLiteConnection object for database was leaked!
I have a database manager this, which I call in my activities with the following code:
DatabaseManager dbm = new DatabaseManager(this);
The code of my database manager class follows now:
public class DatabaseManager {
private static final int DATABASE_VERSION = 9;
private static final String DATABASE_NAME = "MyApp";
private Context context = null;
private DatabaseHelper dbHelper = null;
private SQLiteDatabase db = null;
public static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
//create database tables
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//destroy and recreate them
}
}
public DatabaseManager(Context ctx) {
this.context = ctx;
}
private DatabaseManager open() throws SQLException {
dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (!db.isReadOnly()) {
db.execSQL("PRAGMA foreign_keys = ON;");
}
return this;
}
private void close() {
dbHelper.close();
}
}
When I call a database method, I do the following thing:
public Object getData() {
open();
//... database operations take place ...
close();
return data;
}
But as I said, I still get this SQLite connection leaked warning.
What am I doing wrong?
The bolded font in the citation corresponds to this part in your code:
private DatabaseManager open() throws SQLException {
dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
from: http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html
Approach #1: Use an Abstract Factory to Instantiate the
SQLiteOpenHelper
Declare your database helper as a static instance variable and use the
Abstract Factory pattern to guarantee the singleton property. The
sample code below should give you a good idea on how to go about
designing the DatabaseHelper class correctly.
The static factory getInstance method ensures that only one
DatabaseHelper will ever exist at any given time. If the mInstance
object has not been initialized, one will be created. If one has
already been created then it will simply be returned.
You should
not initialize your helper object using with new DatabaseHelper(context).
Instead, always use
DatabaseHelper.getInstance(context), as it guarantees that only one
database helper will exist across the entire application's lifecycle.
public static class DatabaseHelper extends SQLiteOpenHelper {
private static DatabaseHelper mInstance = null;
private static final String DATABASE_NAME = "database_name";
private static final String DATABASE_TABLE = "table_name";
private static final int DATABASE_VERSION = 1;
public static DatabaseHelper getInstance(Context ctx) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
// See this article for more information: http://bit.ly/6LRzfx
if (mInstance == null) {
mInstance = new DatabaseHelper(ctx.getApplicationContext());
}
return mInstance;
}
/**
* Constructor should be private to prevent direct instantiation.
* make call to static factory method "getInstance()" instead.
*/
private DatabaseHelper(Context ctx) {
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
}
}
The complete example of the above-accepted answer:
It may help someone.
Helper Class:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "sample.db";
private static final int DATABASE_VERSION = 1;
private static DatabaseHelper mInstance;
private DatabaseHelper(#Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public static synchronized DatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new DatabaseHelper(context.getApplicationContext());
}
return mInstance;
}
#Override
public void onCreate(SQLiteDatabase db) {
// create table stuff
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
// drop table stuff
onCreate(db);
}
}
Activity:
SQLiteDatabase database = DatabaseHelper.getInstance(getApplicationContext()).getWritableDatabase();
Cursor cursor = database.query("query");
if (cursor != null) {
while (cursor.moveToNext()) {
// stuff
}
cursor.close();
database.close();
}
private void method() {
Cursor cursor = query();
if (flag == false) { // WRONG: return before close()
return;
}
cursor.close();
}
Good practice should be like this:
private void method() {
Cursor cursor = null;
try {
cursor = query();
} finally {
if (cursor != null)
cursor.close(); // RIGHT: ensure resource is always recovered
}
}

Database initialization error in static method

I have database class. The class and its constructor are shown below.
public class LatLogDBAdapter {
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
I want to use the database in the static method. So that I declare as private static LatLogDBAdapter dbHelper;. Then when i initialize, i have problem. dbHelper = new LatLogDBAdapter(this); dbHelper = new LatLogDBAdapter(DetailMapView.this); make compile error. How can I use this in static method?
If you want to create static method that returns your dbhelper i suggest you to create normal subclass of SQLiteOpenHelper and in this class create public static method that will return new instance. This also is sounds like good reason to use design pattern Singleton
Update:
I mean I want to use this database class inside another java class.
That class has static method and use the database.
Here i create for you basic snippet of code:
public class AdapterWrapper {
private static SQLiteOpenHelper instance;
public static SQLiteOpenHelper getInstance(Context c) {
if (instance == null) {
instance = new DatabaseHelper(c);
}
return instance;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "Example";
private static final int DB_START_VERSION = 1;
public DatabaseHelper(Context cntx) {
super(cntx, DB_NAME, null, DB_START_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// creating tables
}
#Override
public void onUpgrade(SQLiteDatabase db, int old, int new) {
/// drop an upgrading db
}
}
}

NullPointerException on getWritableDatabase()

i have a problem NullPointerException on getWritableDatabase()
public class DatabaseTable extends Activity {
private Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
LBD conection = LBD.get(this);
super.onCreate(savedInstanceState);
}
}
There is an implementation does not work "openHelper.getWritableDatabase()"
public class LBD {
private Context context;
private static SQLiteDatabase db;
private OpenHelper openHelper;
public static LBD get(Context context) {
LBD lbd = new LBD(context);
lbd.open();
return lbd;
}
public LBD(Context c) {
context = c;
}
final public void open() {
openHelper = new OpenHelper(context);
db = openHelper.getWritableDatabase();
}
public class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, "rss_base.db", null, 3);
}
}
}
I realized, I forgot to initialize the onCreate Thanks to everyone
Most likely your Context
openHelper = new OpenHelper(context);
is null. Make sure that your Context is set. But i recommend to you provide more details, add here your logcat.
Problem is not in your Database Class, its at DatabaseTable.onCreate()..... java:27
Please check it out.
Thanks,
Haps.

GetReadableDatabase error android

I created a DBTest class SQLiteOpenHelper
Then I called this from my main UI.
It crashes when I hit the DB.GetReadableDatabase () and the log is no help, just says null pointer, but I don't know where to look.
Everything works if I use
SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
Same database
Here is the Class for the helper and below the error:
public class DBTest extends SQLiteOpenHelper {
private static String DB_NAME = "DB";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DBTest(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
Below is where the error happens:
public class Main extends Activity
{
DataBaseHelper db = new DataBaseHelper(null);
static SQLiteDatabase Db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SQLiteDatabase Db;
DBTest db1 = new DBTest(null);
Db = db1.getReadableDatabase(); <<< blow up here
}
}
DBTest db1 = new DBTest(this.getApplicationContext());
Context can't be null

Categories

Resources