Connecting to a single database - android

I have 2 classes which connect to a database. But with my current implementation I have to connect to 2 different databases.How can I fix this? If I use the same name for both databases it gives me an error
One class.....
public static final String DATABASE_NAME = "140398L.db";
Context context;
public PersistantAccountDAO(Context context) {
super(context, DATABASE_NAME, null, 1);
this.context = context;
}
Other class......
public class PersistantTransactionDAO extends SQLiteOpenHelper implements TransactionDAO {
public static final String DATABASE_NAME = "140398L";
public PersistantTransactionDAO(Context context) {
super(context, DATABASE_NAME, null, 1);
}

The DatabaseName is different, one class is 140398L.db and the other is 140398L

Related

Memory leaks in context

I have a class App which extends Application and has a static method which returns context(which is static).
public class App extends Application {
private static Context context;
#Override
public void onCreate() {
super.onCreate();
context = this.getApplicationContext();
DBHelper dbHelper = new DBHelper();
DatabaseManager.initializeInstance(dbHelper);
}
public static Context getContext() {
return context;
}
}
Now in the DBHelper class which extends SQLiteAssetHelper in the constructor, i have this:
public DBHelper() {
super(App.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
}
This is the DataBaseManager class:
public class DatabaseManager {
private Integer mOpenCounter = 0;
private static DatabaseManager instance;
private static SQLiteOpenHelper mDatabaseHelper;
private SQLiteDatabase mDatabase;
public static synchronized void initializeInstance(SQLiteOpenHelper helper) {
if (instance == null) {
instance = new DatabaseManager();
mDatabaseHelper = helper;
}
}
public static synchronized DatabaseManager getInstance() {
if (instance == null) {
throw new IllegalStateException(DatabaseManager.class.getSimpleName() +
" is not initialized, call initializeInstance(..) method first.");
}
return instance;
}
public synchronized SQLiteDatabase openDatabase() {
mOpenCounter+=1;
if(mOpenCounter == 1) {
// Opening new database
mDatabase = mDatabaseHelper.getWritableDatabase();
}
return mDatabase;
}
}
Everything works fine, but there is a design problem because context fields should not be static. How do I use a context in DBHelper while keeping the code working and the field non-static?
You can pass ApplicationContext inside the DBHelper constructor like below:
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
and then
DBHelper dbHelper = new DBHelper(getApplicationContext());

Upgrade read-only database

I'm using SQLiteAssetHelper for importing ready databases into my app.
Now I want to release a 2nd version of my database, but when users update the app, the database in not updating. I see documentation and saw I must use setForcedUpgrade(), but i don't know where to use it, I'll appreciate if you guide me. :)
MyDatabase.java :
public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "database.db";
private static final int DATABASE_VERSION = 2;
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}}
And I read database with these:
MyDatabase my;
SQLiteDatabase sq;
my = new MyDatabase(getApplicationContext());
sq = my.getWritableDatabase();
Thanks by the way.
For your example:
public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "database.db";
private static final int DATABASE_VERSION = 2;
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
//FORCE UPGRADE BY DELETING OLD DATABASE
setForcedUpgrade(DATABASE_VERSION);
}}
In Android you should use SQLiteOpenHelper (http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html). Inherid your own class and overwrite onCreate and onUpgrade.

Android: understand this.context

I am trying to understand a class responsible to make a connection to a DB
the code is:
public class DBAdapter
{
final Context context;
DatabaseHelper DBHelper;
SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//All the necessary method are implemented.
}
}
So to make a conection i should just"
DBAdapter db=new DBAdapter(this);
My question is what does this line this.context = ctx; does:
Why we can not omit that and simply :
public DBAdapter(Context ctx)
{
DBHelper = new DatabaseHelper(ctx);
}
Through this keyword you are specifying that the address or the reference of activity class which is coming to the DBAdapter method in ctx variable which is of Context type will be assigned to class level Context variable.
Though you can remove class level variable and this.context = ctx; line and simply write as you had specified
public DBAdapter(Context ctx)
{
DBHelper = new DatabaseHelper(ctx);
}
but if you want to use ctx (context reference) value to all over class it is advised to use class variable.
According to your class code. you does not required to assign context to another context variable . this is simplified code.
public class DBAdapter
{
DatabaseHelper DBHelper;
SQLiteDatabase db;
public DBAdapter(Context ctx)
{
DBHelper = new DatabaseHelper(ctx);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//All the necessary method are implemented.
}
}
To assign context to another variable is useful when you use context in some other methods as well. because the scope of the variable is limited to its method. you cannot use it outside of the constructor(according to your code)
If you're following the tutorial, they have a Context class variable because they reference it in the open method.
public DbAdapter(Context ctx)
{
this.mCtx = ctx;
mUsername = PreferenceManager.getDefaultSharedPreferences(ctx).getString(Preferences.USERNAME, "");
}
public DbAdapter open() throws SQLException
{
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}

get Contex in extended SQLiteOpenHelper class

I have database and i want fill it with some values from xml file.
I'm using this code stream = context.getResources().openRawResource(R.xml.test_entry); to define the stream, but context make error "cannot resolve symbol 'context'".
I tried replace context with getActivity(), getContext(), this, class name and it still doesn't work. I need some help...
public class DatabaseHelper extends SQLiteOpenHelper {
<...>
public DatabaseHelper(Context context) {
super(context, dbName, null, dbv);
}
public void onCreate (SQLiteDatabase db) {
<...>
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+tableName);
onCreate(db);
/////////////////
loadTestValuyes(); <----- My function
/////////////////
}
public void loadTestValuyes() {
test_addEntry stackOverflowXmlParser = new test_addEntry();
List<Entry> entries = null;
InputStream stream = null;
///// I need context here
stream = context.getResources().openRawResource(R.xml.test_entry);
/////////////////
try {
entries = stackOverflowXmlParser.parse(stream);
} finally {
if (stream != null) {
stream.close();
}
}
for (Entry entry : entries) {
<...>
}
}
}
Thanks
You're passing a Context as a constructor argument. Just store it to a member variable:
private Context mContext;
public DatabaseHelper(Context context) {
super(context, dbName, null, dbv);
mContext = context;
and then use mContext where you need a Context.
You can save a reference to the Context object as an instance variable and use it wherever you need it:
public class DatabaseHelper extends SQLiteOpenHelper {
private Context mContext;
public DatabaseHelper(Context context) {
super(context, dbName, null, dbv);
mContext = context;
}
}

android: SQLite Db error

hello i am building a SQLite Db for my android application . this is the code :
package com.example.pap_e;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class FeedsDbAdapter {
private final Context mCtx;
private static final String DEBUG_TAG = "RSSDatabase";
private static final int DB_VERSION = 1;
private static final String DB_NAME = "rss_data";
public static String TABLE = "list";
public static final String ID = "_id";
public static final String RSS = "_rss";
public static final String TITLE = "_title";
public static final String PUBDATE = "_pubdate";
public static final String DESCRIPTION = "_description";
public static final String LINK = "_link";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static class DatabaseHelper extends SQLiteOpenHelper{
DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE_TABLE"+TABLE+"("+ID+ "integer PRIMARY KEY AUTOINCREMENT,"+RSS+"text NOT NULL,"
+TITLE+"text NOT NULL,"+PUBDATE+"text NOT NULL,"+DESCRIPTION+"text NOT NULL,"+LINK+"text NOT NULL"+")");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE);
onCreate(db);}
}
public FeedsDbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
public boolean updateAnakoinosi(long rowId, String rss, String title,
String pubdate, String description, String link) {
ContentValues args = new ContentValues();
args.put(RSS, rss);
args.put(TITLE, title);
args.put(PUBDATE, pubdate);
args.put(DESCRIPTION, description);
args.put(LINK, link);
return mDb.update(TABLE, args, ID + "=" + rowId, null) > 0;}
public Cursor fetchAllAnakoinoseis() {
return mDb.query(TABLE, new String[] { ID, RSS, TITLE, PUBDATE,
DESCRIPTION,LINK }, null, null, null, null, null); }
}
The thing is that i get an error at public class FeedsDbAdapter that says:"The blank final field mCtx may not have been initialized" but i had it initialized using private final Context mCtx; Am i missing something here ? Thanks a lot in advance!
You didn't initialize the context yet. You have to initialize it inside FeedsDbAdapter constructor like :
public FeedsDbAdapter (Context context){
mCtx = context;
}
first declare FeedsDbAdapter constructor, because you use FeedsDbAdapter class through its constructor in other classes ans the other activity context will assign to this current context.
Change your code to :
private static class DatabaseHelper extends SQLiteOpenHelper{
DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
mCtx = context;
}
This question of yours relates to java. This line private final Context mCtx; is just a declaration of field mCtx of type context. And as this field has been declared as final, It has to be iniliazed inside the constructor mCtx = context;. Even if mCtx is not declared as final, it has still to be initialized before being used.
Thats because your class is static... Remove static from your class and change your code to
DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
mCtx = context;
}

Categories

Resources