I need to create an instance of a class that extends SQLiteOpenHelper. I cannot create an empty constructor within the class that extends SQLiteOpenHelper, so how do I initialize the instance in my other class?
For example, I cannot just do this:
MyDatabaseManager myDatabaseManager = new MyDatabaseManager();
because the constructor of MyDatabaseManager requires a context, name, factory, and version as parameters, but I also get an error when I try to create an empty construcor within the MyDatabaseManager class, because it extends SQLiteOpenHelper.
So how would I go about creating an instance of that class in another class?
Related
I have a fragment that needs to connect to the database to view its contents and in order to do that I need to get a cursor to my database. Now I have a database class as "DB" and a fragment class "FRAG" . To get a cursor I need to call certain methods of "DB" class inside my fragment. Now to call a method of "DB" class I need a object of "DB" class, the problem is that I am unable to initialize a constructor of "DB" class in fragment class. Syntax is as follows-
Original database constructor is
public DB(Context context, String name, CursorFactory factory,int version) {
super(context,"database", factory,1);
}
I am initializing its object in fragment as follows-
DB ob=new DB(this,"database",null,1);
It gives me a syntax error as -
The constructor DB(Frag, String, null, int) is undefined
How do I initialize a object in this case. Kindly help.
Activity is a descendant of the Context class, not the Fragment.
You have to call the constructor with:
new DB(this.getActivity(),"database",null,1);
where this refers to your Fragment
In the docs, it says I should make the new class like this:
class MyView extends GLSurfaceView {
public MyView(Context context) {
super(context);
setRenderer(renderer);
}
}
Now I tried to re-do that in Scala:
class BaseGameActivity extends Activity {
object glview extends GLSurfaceView(this) {
setRenderer(renderer)
setEGLContextClientVersion(2)
}
}
However, the App crashes now with the exception "java.lang.IllegalStateException: setRenderer already called for this instance". I suspect this has to do with the way Scala calls the super-constructor.
I've tried to find out how to override the constructor in the way the docs describe, but couldn't find it. I'd appreciate any hint.
It seems to me that your are propagating the call to a different constructor from the base class. You are passing a reference to this instead of a reference to the Context object. It might be that this other constructor is calling setRenderer.
Could you try to create an inner class MyGLView like this:
class MyGLView(ctx: Context) extends GLSurfaceView(ctx) {
setRenderer(renderer)
}
And see what happens?
The problem is that object does not allow arguments to its constructor. Top-level objects must be initializable without any arguments (nobody calls their ctors). In your case you have an inner object, which can reference the members of the surrounding class instance. If you really need an inner object in your Activity class, you could do:
object glview extends GLSurfaceView(ctx) {
setRenderer(renderer)
}
where ctx is a member of the surrounding class.
In java likewise in scala constructors are not inherited.
So you can not override thing, you didnt inherit. And you should use one of existing constructors for base class. If all of them are calling setRenderer(renderer) it will be called during constructing super object and you obviously should not call it second time in a subtype constructor ( wheither it class, object or mixing-in trait ).
I handle login for my application in a class that extends application. The application then maintains an object of this class at all times. This means that I can access that specific object from any class that extends activity or service by calling
LoginModeller lm = ((LoginModeller)getApplicationContext());
However, I now need to access the object from a class that does not extend activity or service (It extends nothing). Is there some way to access the application context from a class like this, or I do have to re-factor my LoginModeller as a singleton or something?
Who creates this object? In your constructor you can pass in a Context and store it as an instance variable:
private final Context context;
public MyObject(Context context) {
this.context = context;
...
I don't know if you are using DI with roboguice but I am :)
From my point of view, the cleanest way to do this is using a staticInjection. Here's how.
I want to use a singleton pattern to hold a database and some other data/methods for my Android application.
I realize there are many reasons against singletons, but for this case I'd like to use it.
I've sub-classed UIApplication and made a data class within it called MyAppData.
MyAppData needs to have access to the SQLite database.
When I create the databse, I need to pass a context. I could pass the application context, but it will not directly relate to MyAppData.
I don't know if this wlll cause problems with my code.
So my thought is to have MyAppdata extend android.content.ContextWrapper. I don't think I should extend Activity because it's really not an activity, its a data class with methods to access the database.
I'm wondering if I extend ContextWrapper will there be something deep in the code I'm missing that will cause big problems down the road (memory leaks, etc).
This may not be the ideal approach to this (and I've considered other options), but my goal is to:
Have a singleton class in UIApplication that can encapsulate the database and be retrieved easily from any activity in my app.
Thanks in advance for your suggestions/warnings/advice.
Subclass android.database.sqlite.SQLiteOpenHelper and android.app.Application (with the latter being properly declared in AndroidManifest.xml).
Now,
public class MyApplication extends Application {
private static SQLiteOpenHelper openHelper;
#Override
public void onCreate() {
super.onCreate();
openHelper = new DbManager(this);
//
}
public static SQLiteDatabase getDB() {
return openHelper.getWritableDatabase();
}
}
Then have helper DAO classes that will perform instertions/updates/etc.
That's what I'm using in all of my apps.
I've used this approach:
Create a class responsible for managing the db, let's call it DBUtil. This class will extend android.database.sqlite.SQLiteOpenHelper. You can pass a reference to the application context to the constructor of this class. This class will contain methods for creating the db, adding, removing and retrieving items.
Create another class, let's call it AppCore, create a static instance of the DBUtil and a static init() method that accepts an ApplicationContext object
public class AppCore
{
public static var dbUtil:DBUtil;
public static void init( ApplicationContext context )
{
dbUtil = new DBUtil( context );
}
}
Then in the onCreate() method of our your application's main Activity, initialize the AppCore class.
#Override
protected void onCreate(Bundle savedInstanceState)
{
AppCore.init( getApplicationContext() );
}
So, it's not really a Singleton. Instead, the DBUtil instance is maintained as a static property, yet still accessible throughout your application, such as this:
AppCore.dbUtil.createNewRecord( params );
Also, I found this tutorial to be very helpful when getting started with this topic: http://developer.android.com/guide/tutorials/notepad/index.html
I have a DBHandler class that will be used in several activities to do some crud operations. created a MyApp class (extends Application) to hold one instantiation of the DBHandler.
My DBHandler class needs a Context to create the SQLiteOpenHelper to populate the db, etc.
That's where the problem starts: in my MyApp constructor, I want to instantiate my DBHandler, so I wrote this:
public MyApp() {
super();
dbh = DBHandler(<WHAT DO I PASS HERE>);
}
I tried getApplicationContext(), getBaseContext(), 'this'... nothing seems to be a fully-instantiated context at this point. I get a NPE when the SQLiteOpenHelper tries ctx.getResources().
A workaround: create the DBHandler and set it in the onCreate of my main class. -> UGLY (call me a aesthetician)
Question: is there a way to do it when Android creates MyApp?
Thanks!
Creating your DBHandler in MyApp.onCreate() is the proper way to do what you want.
#Override
public void onCreate() {
super.onCreate();
dbh = new DBHandler(this);
}