I have an app where I store some data in a SQLIte database.
And what I'm trying to do is to get my DB opened only once at the start of my app and then use the same instance of my DB.
The idea is not to open my DB in every activity I need it.
One of the solutions I got was this-create a class that extends Application and then open the DB there:
This is how the code looks like:
public class MyApplication extends Application{
private static DBAdapter db;
public void onCreate()
{
db=new DBAdapter(getApplicationContext());
db.createDatabase();
db.openDataBase();
}
public static DBAdapter getDatabaseAdapter()
{
return db;
}
}
So in every activity of my app where I need to connect with my DB I do something like:
MyApplication myApplication = (MyApplication) this.getApplication();
DBAdapter db= myApplication.getDatabaseAdapter();
But I'm not very sure if my DB gets opened only at the beginning of my app...or it gets opened everytime I do this:
MyApplication myApplication = (MyApplication) this.getApplication();
?
Or if anyone has a better solution please tell me:).Thank u
It will be opened only once because you are calling it in onCreate method of Application class which will be called when the application is starting, before any other application objects have been created. You can look at one of my project here is link.
Hope this help.
EDIT: About Application Class : Android will automatically create an instance of that class and make it available for your entire application. You can access it from any context using the Context.getApplicationContext(). So there will be only one instance of Application which will be shared.
An alternative to your approach can be making one SingleTon Class where you can keep the reference to your open dbconnection so that it could be reused.
Since for any android application there's only single instance for applcation class spread across all the activities so your db gets open only at the start of android application.
Related
I would like to automatically insert some crafted code to any possible parts of the target app code. This crafted code includes a "context.startService()" to contact with a remote service from another app. How can I automatically get this context instance so that I can call startService() from anywhere within the app code?
Thanks a lot in advance. Any inputs are highly appreciated.
If I understand correctly, you want to start a service from anywhere within your codebase without passing around context objects. The solution below is a way to do this but look at this post to get a better understanding of why this isn't always the best solution.
Create a class that extends from Application:
import android.app.Application;
public class MyApplication extends Application {
private static Application sInstance;
public MyApplication() {
sInstance = this;
}
public static Application getInstance() {
return sInstance;
}
}
This will give you access to your application's context so you can start a service from anywhere.
Now in some part of your code:
void foo() {
MyApplication.getInstance().startService(new Intent(MY_SERVICE));
}
create a new method, that gets your context, and then calls your service with said context, then call that method instead.
shouldnt change your code much....
when I made an SQLite database for an Android app I made a helper class that does not extend any other class. it is just to set up the database, in this example it is called PlayGame. it has a private class inside it shown here:
private static class DbHelper extends SQLiteOpenHelper
when I use the database for any reason in the main UI class called SQLiteExample I have to create an instance every time like this,
PlayGame entry = new PlayGame(SQLiteExample.this);
entry.open();
entry.createEntry(name, hits);
entry.close();
I am creating many instances of this database class called PlayGame in the other Activity class. Like in most all of my methods have to make instances to do the required function like read information into or out of the database.
so I read in best practices of android documentation that creating instances is heavy on memory and is best avoided. If this is the case is there a better way to do this? and does my example look like a bad use of memory?
Use singleton for every instance you want to use. instead of create a new instance of any object you will use the same object.
http://en.wikipedia.org/wiki/Singleton_pattern
How do I handle references between Fragments showing list of data and different threads/classes updating data in the background. Because of this I need to be able to force update from outside of the Fragments via Observer-inf or something similar.
Currently I'm using dummy factory-class to create a new SqlLiteDatabase object, based on my default settings for it.
public static SQLiteDatabase initFor(Context context) {
db = context.openOrCreateDatabase(NAME, SQLiteDatabase.CREATE_IF_NECESSARY, null);
db.setLocale(Locale.getDefault());
db.setVersion(1);
db.setLockingEnabled(true);
return db; }
Then I call this from each fragment and sets up adapters, the same applies to the data-inserter-threads. To close the db, I override my activity's onDestroy() and call: initFor(this).close(); .
This is very ugly and it fails on orientation change. I'm thinking of SQLiteOpenHelper but I don't know how it will help me.
You should access your database on another thread (in a Service) then have this talk to one class (which could be your helper), you then access this helper class through a singleton initialized in a class that extends Application. You can get your Application class from any of your fragments by calling
((YourApplication) context.getApplicationContext()).getGetDatabaseHelper();
I have followed this tutorial to use SQLite db in my android app.
Since I am a beginner I'm having problems understanding "context" parameter used in the example.
I want to call adapter and insert/update/delete records from a class that does not extend activity which in this example stands for context.
Now I don't know what to pass in the adapter as context, since I'm not calling adapter from activity.
Can someone please explain this?
Pass the ActivityName.this as class context as argument to the adapter class's constructor
the ActivityName is the name of the Activityclass in which you are calling the adapter
you could imagine that the context defines WHERE/WHEN the sqlite database exists. sqlite databases do not exist on their own, they exist within the confines of your activity, thus in your activity's context.
for the next steps you must understand that the context is a dynamic "thing" (in reallife you could imagine it as someone's HERE and NOW). the context is individual to the activity and its moment, just as your here and now are yours and yours only and change over time.
if you are calling a class from within your activity, then this does the trick (passing the activity's context from within the activity itself is OK - sorta like you saying to your buddy: this is how i am feeling NOW).
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context contextNew = this;
myClass(contextNew);
an easy all around solution (panacea) would be to create a static Context variable (contextVariable) inside MyActivity and access it directly from without via: MyActivity.contextVariable. but that does not work, because you get an error when you try to declare/use a static Context variable.
So, if you plan on using sqlite inside a service that is NOT called from within the main activity, like, for example, a service triggered by a broadcast receiver (neither a service nor a receiver have a context per se), then you must access the original application's context from within said receiver.
accessing the original activity's context is simple, but far from obvious.
this works for me (thanx #ZiGi and #Cristian):
import android.app.Service;
import android.content.Context;
public class BatchUploadGpsData extends Service {
public Context contextNew;
#Override
public void onCreate() {
contextNew = getApplicationContext();
this is an example from working code that uploads navigation data to a database on the web every time the android device connects to a WIFI network. i have a receiver listening to connectivity changes (existing as a separate class called directly "from" Manifest file).
i hope that this makes sense, if you want more detail on this, check out this post of mine where i have the complete (barebones) code for said receiver.
As you see in the example, there is a context passed to the ToDoAdapter. You can pass activity as a context or activity.getApplicationContext(). Read about context here.
I have a class:
public class DbAdapter {
private DbHelper dbHelper;
private SQLiteDatabase db;
private final Context context;
...
}
and i want have it available in all activities. The class provides access to my sqlite database.
What is the most elegant and neat way to do it? I thought about creating object in each activity (it should "connect" me to the same database, right?).
You can achieve it extending the Application class. Google has this to say about it:
Base class for those who need to
maintain global application state. You
can provide your own implementation by
specifying its name in your
AndroidManifest.xml's
tag, which will cause that class to be
instantiated for you when the process
for your application/package is
created.
There is normally no need to subclass
Application. In most situation, static
singletons can provide the same
functionality in a more modular way.
If your singleton needs a global
context (for example to register
broadcast receivers), the function to
retrieve it can be given a Context
which internally uses
Context.getApplicationContext() when
first constructing the singleton.
I have done it myself like this:
public class App extends Application {
private DbHelper dbHelper;
#Override
public void onCreate() {
super.onCreate();
dbHelper = new DbHelper(this);
}
public SQLiteDatabase getDatabase(){
return dbHelper.getWritableDatabase();
}
#Override
public void onTerminate() {
super.onTerminate();
dbHelper.close();
}
}
Then you just access it calling getApplicationContext.getDatabase()
You may take a look at the Singleton Pattern, it gives the opportunity to make a class have only one object created and to make this object accessible from everywhere. Hope this helps.
I think the best way to implement this is to use Service. The Service will keep reference to DbAdapter and all your activities will connect to the Service. When activity is connected to the service it'll keep the reference to it and every time it needs db access it'll use to get the DbAdapter. Using this approach you'll have control over your db connection. If no activities are connected to the service than no one is using the db connection and you can free it.
Have a look at ContentProviders. They're made for accessing data. And regardless of all the emphasis on "sharing data between applications" in the link, they don't have to be public - you can use them as a centralized way to access data in your app.
This blog entry on 'Writing Your Own ContentProvider' shows some code for setting up a ContentProvider that works within one application.