Best practice: Managing android database references between fragments - android

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();

Related

How synchronized on activity work, given activity is recreated on orientation change

I have an activity, in the onCreate function I have created a Thread which reads from XML file and populates the Database and also populates member dataStructures.
I have created synchronized methods to carry out DB population and DataStructure population.
Since the lock is on activity[synchronized methods], will it cause any issue when activity is recreated because of orientation change or any config change?
Is it correct to use synchronized methods here? or should I use synchronized blocks?
How do I handle or take care so that DB is not corrupted?
How do I ensure only one instance of DataBaseHelper is present even over activity recreations?
If you want to do what I think you want to do then I suggest to do the following:
Create a thread(HandlerThread named DbAsyncThread or whatever) that handles all the methods for all the db methods.
Method should use synchronized blocks. Synchronized methods I use when there is a public static method. It always depends on what you want to achieve.
Incorrect states of db you can handle via exceptions. If there is an exception you throw it or pass it to the ui so that the users or you are notified.
Use callbacks. If there is a problem notify via callback about the problem. If there is no context involved there should not be any problem.

is the a better way? on instantiating objects for SQLite

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

passing data through activities in background

I am working on database for a game.
I would like to get the score from one activity and call it in database activity, where it will be updated in the database by using intent, the game gets paused when intent is fired.
I have also tried using application class (suggestions on that are welcome).
Is there any way to pass data among activities by firing intent in background so that it does not interrupt the gameplay?
Your database should not be in an Activity. An Activity represents one screen (or one use-case) in your application, and should not represent implementation details like a database-class.
As an alternative, you can put your database code in a Singleton class that can be accessed from everywhere in the same application. You can also create the database in the Application's onCreate method and store it in a static field there or just create a separate class that exposes static methods to access the database.
If you are somehow dead-set on using Intents, you would need to use a database Service instead of an Activity. This way the current Activity will remain on top when you send the data to the service. But that would complicate things a lot compared to a simple static class/singleton approach.
You seem to have a big mix up: There shouldn't be a database activity. You should create a database helper class and make it a member variable in your application class.
// inside application class
private static MyDatabaseHelper mMyDB;
public MyDatabaseHelper static getDatabase() {
if (mMyDB == null) {
// mInstance should be the application instance, means make the
// application class a singleton
mMyDB = new MyDatabaseHelper(mInstance);
// the constructor should open/create the database
}
return mMyDB;
}
With this you can work with your database from everywhere.
With that you can easily update every value from everywhere. So no need to fire an intent to pass values around. Instead just update your database directly.
There are multiple ways to this.
You can use handlers, services, then use setresult which give call back to onactivity result of the parent activity.
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle b = new Bundle();
b.putInt("key", 1);
intent.putExtras(b);
startActivity(intent);

problem in understanding how to use database SQLite

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.

Store shared object for all activities

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.

Categories

Resources