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;
}
}
Related
I wanna know how to design lazyholder singleton pattern with arguments.
I know only when no argument there is but dont know with arguments.
the problem is like below when construct private static final DBHelper INSTANCE = new DBHelper();
how can I solve it?
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
this.context=context;
}
public static DBHelper getInstance(){
return DBHelper.DBHelperHolder.INSTANCE;
}
private static class DBHelperHolder{
private static final DBHelper INSTANCE = new DBHelper();
}
You can use DCL pattert, for example:
public class DBHelper {
private static volatile DBHelper instance;
public static DBHelper getInstance(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
if (instance == null) {
synchronized (DBHelper .class) {
if (instance == null) {
instance = new DBHelper(context, name, factory, version);
}
}
}
return instance;
}
}
But you need to supply arguments every time you call getInstance.
In addition to #Bracadabra's answer,
It is recommended to add private constructor() as it is singleton pattern and we want to restrict new object creation of our class DBHelper
I prefer LOCK object for synchronisation (to be thread safe)
We should restrict clone() calls also, so that outside code can not clone this class by .clone() call. So, override clone() method and return CloneNotSupportedException() from it.
public class DBHelper {
private static DBHelper instance;
// LOCK object for synchronisation
private static Object LOCK = new Object();
// Private Constructor
private DBHelper() { }
public static DBHelper getInstance(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
if (instance == null) {
synchronized (LOCK) {
if (instance == null) {
instance = new DBHelper(context, name, factory, version);
}
}
}
return instance;
}
#Override
protected DBHelper clone() throws CloneNotSupportedException {
return CloneNotSupportedException();
}
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());
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
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;
}
Could you please help me with error "java.lang.NullPointerException". I use custom listpreference to show elements from database. There two files CustomListPreference.java and DbHelper.java
CustomListPreference.java
public class CustomListPreference extends ListPreference {
CustomListPreferenceAdapter customListPreferenceAdapter = null;
Context mContext;
private SQLiteDatabase db;
DbHelper dbHelp = new DbHelper(mContext);
public CustomListPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = context;
mInflater = LayoutInflater.from(context);
}
#Override
protected void onPrepareDialogBuilder(Builder builder)
{
...
try {
db = dbHelp.getReadableDatabase();//I get error java.lang.NullPointerException
...
}
DbHelper.java
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DbHelper extends SQLiteOpenHelper {
static String DATABASE_NAME="myBase";
public static final String KEY_NAME="name";
public static final String KEY_ID="id";
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table tUser ("
+ "id integer primary key autoincrement,"
+ "name text,"
+ "exists integer" + ");");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
}
because your mContext is null
place this line inside constructor..or any of your other preferece methods before using it
dbHelp = new DbHelper(context);
Context mContext;
private SQLiteDatabase db;
DbHelper dbHelp = new DbHelper(mContext);
The mContext you passed to DbHelper constructor is null.
You should not initialize any class member requiring a valid Context until onCreate() anyway.