I want to get the name of an opened database, for which I have a reference via a SqliteOpenHelper. No problem with API level 14 (getDatabasename). But I need it to work with API level 10 (hard requirement--this is for a class I'm taking).
The only idea I've come up with so far is storing the database name myself for future use--either in the class in which I need it or as a member of a subclass of SqliteOpenHelper. Is there a better way? Thanks.
getDatabaseName() returns the exact same name that you provided in the SqliteOpenHelper constructor, so the best is probably to store it in a member variable of a subclass. It will be more flexible if later you have another project where you have the same problem.
but dont you already have the database name since your opening it and passing it to the constructor of SqliteOpenHelper ? So just subclass SqliteOpenHelper and create the method getDatabaseName() yourself and let it do what you want.
this seems to be more about object oriented principals. Let me know if you need code or if im mistaken.
I grepped the code . the function your looking for simply stores the variable you set in the constructor:
public String getDatabaseName() {
return mName;
}
so again make your own
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.1_r1.2/android/database/sqlite/SQLiteOpenHelper.java#SQLiteOpenHelper.getDatabaseName%28%29
Related
Ok here is same question why database name must be static?
but i know already that why we should declare database name static & final.
And i tried to give non static database name into constructor of SQLiteOpenHelper but end up with an error the field can't be quoted from the static context
I want to know/find the source code or particular line where it was decided to make those ( database & version ) static.
I looked already https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/database/sqlite/SQLiteOpenHelper.java but couldn't find.
It's about Java, not about Android sqlite.
When initialising an object instance, constructor is invoked before initialising member fields. The database name is a constructor argument and needs to be initialised when invoking the constructor. When it's static, it's not an instance member but a class member that is initialised earlier when the class is first accessed.
See Java order of Initialization and Instantiation
This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 3 years ago.
Here is my method:
public Cursor rawQuery(String sql, String[] selectionArgs) {
try {
return m_db.rawQuery(sql, selectionArgs);
} catch (SQLiteException e) {
reportException(Context.getApplicationContext(), e);
return null;
}
}
Android Studio (3.5.3) complains saying
Non-static method getApplicationContext() cannot be referenced from a static context.
I don't see any static context here. rawQuery is a perfectly good class method of a class which is a wrapper around SQLiteDatabase to save me having to check for exceptions on every call. The exception checks are needed because it's accessing a public database and some other process may have modified it in such a way that my operation fails (for example by dropping one of my tables). It is (currently) only created and its methods called from an Activity. Of course I could pass the calling activity's context, but this is clumsy since it isn't needed most of the time and IMHO it's very poor programming style to include extra arguments in the methods of a wrapper class.
reportException does what its name says and writes a log file or displays a Notification or a Toast, depending on circumstances, and all of these need a context.
I've seen suggestions on the net to create a static instance of a subclass of Application to cache the application context. As commenters have pointed out, this doesn't always work if you need the application context in a class constructor (or anything which is called from one), but I don't expect to do this. My wrapper class is created as needed when I want to access the database. However I'm not sure if tha Application subclassing trick works if I open a database in a background server which may get kicked out of memory when not active and later restarted by the OS. It may be that the only solution is to cache the creator's context in the constructor of the wrapper class: this only requires passing the context once. However I don't much like the idea of keeping a copy of the passed context: it looks inelegant and a potential problem with garbage collection since I have to take care not to use the cached context when creating anything persistent..
However I still don't see Android Studio's justification for complaining in the case shown. I tried removing all the calls to rawQuery and it still complains, so it isn't walking the call tree to look for a non-static context. It looks as if it may be complaining if getApplicationContext is used in any class which isn't a subclass of Activity, which certainly isn't justified.
I don't see any static context here.
The "static context" referred to by the error message is the way you are calling the method: Context.getApplicationContext(). Since you are using the Context class name, this counts as a "static context". You need a Context instance in order to call getApplicationContext().
Of course I could pass the calling activity's context, but this is clumsy since it isn't needed most of the time and IMHO it's very poor programming style to include extra arguments in the methods of a wrapper class.
Yes, I agree that you should keep your argument list as trimmed down as possible. You say that this method is a wrapper around SQLiteOpenHelper which requires a Context as one of its constructor parameters. So presumably your own constructor takes a Context to pass to the wrapped SQLiteOpenHelper instance. One solution is to keep that Context as a field in your class. Then you can just use this.context.
I have a SQLiteOpenHelper that wraps my Database. the SQLiteOpenHelper subclass is implemented as Singleton to avoid MultiTread problems and it seems to work quite well.
The problem is: testing classes that uses the database.
In AndroidTestCase i want to test methods that depends on DB in isolation so i use
setContext(new RenamingDelegatingContext(getContext(), "test_"));
and than use the IsolatedContext to get a separate empty instance of the db.
So, the android app need the singleton but Junit need a simple instance.
The only approach i found at the moment is declare SQLiteOpenHelper subclass with two contructors , one static that return the singleton instance and another that return a new instance . Than add to every class that use the db add one constructor to use the singleton an other that use a new instance.
This approach it is very ugly and error prone , so there is a more logical elegant way to do so?
(ps i'm not using ContentProvider and not interested in so please do not suggest them as solution)
Is it necessary to extends SQLiteOpenHelper.I just want to copy the database(read only) from aseets folder.
It is not necessary to extends SQLiteOpenHelper,To create and upgrade a database in your Android application you usually subclass "SQLiteOpenHelper". In this class you need to override the methods onCreate() to create the database and onUpgrade() to upgrade the database in case of changes in the database schema. Both methods receive an "SQLiteDatabase" object.
SQLiteOpenHelper provides the methods getReadableDatabase() and getWriteableDatabase() to get access to an "SQLiteDatabase" object which allows database access either in read or write mode.
For the primary key of the database you should always use the identifier "_id" as some of Android functions rely on this standard.
if you just want to copy the database then its fine.
But if you want to read,update,delete or create new record in database then there are two ways
Extend sqlitedatabase
Use ormlite wrapper
Hope this will help.
Yes, it not need ,if you just want copy database file and don`t operate database, it just a file I/O operate.
In My Application i stored the data in to the One class said name as abc. in this class there are only getter setter methods available. I am going to store the String array in to that class by getter setter method. So it is Possible that from other activity to fetch all available values that are inserted in to that class ??
If yes then let me know.
And if no then how it is possible ?
Yes we can do this.Make those functions public and you can use them using object of the corresponding class.Also you can make them static(but not recommended) and use them using class name itself.They are made for this purpose only.
yes, we can do you can store values in one activity and access in another activity.
Refer this How can I access stored values of a Bean from inside another Class