Database connection is opened by creating object or using getwritabledatabase - android

My application has 7 activities and all are highly dependent on database and each activity when accessed will query database a lot.
For this issue I have created a singleton database object for the database class and for every operation I am calling below statement.
Database.getInstance(c1).getWritableDatabase()
for inserts, selects and deletes I am using like below
-- insert Database.getInstance(c1).getWritableDatabase().insert
-- select Database.getInstance(c1).getWritableDatabase().rawquery
-- delete Database.getInstance(c1).getWritableDatabase().rawquery
I am using this way because by this only one object is used in whole application and multiple objects won't be created.
But when searching the web, I learned that getWritableDatabase() will open a connection to database. Now I am confused whether object to database class will open a connection or calling getwritabledatabase will open a connection.
I am worrying because I feel I am creating too many connections unknowingly.
Edit
I have tried to create a writable database object as below in every activity and use that object in that actovity but it returned me database locked exception hence I was forced to use the Database.getInstance(c1).getWritableDatabase() for every db operation
I have created as below
Sqldatabase sd=Database.getInstance(c1).getWritableDatabase()
I am wanting to discover how the database should be opened and where it should be closed to make a application stable and avoid memory leaks. I am am a beginner to Android, and keen to find out if my design is a valid one.
Edit
Database file
public class Database extends SQLiteOpenHelper{
private static String dbname="Director";
private static int dbversion=1;
SQLiteDatabase db;
private Context m1Context;
private static Database minstance;
public Database(Context context) {
super(context, dbname, null, dbversion);
// TODO Auto-generated constructor stub
}
public synchronized static Database getInstance(Context m1Context){
if (minstance==null){
minstance=new Database(m1Context);
}
return minstance;
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
STable st=new StockTable(m1Context);
BTable bt=new BrokerageTable(m1Context);
SList sl=new StockList(m1Context);
db.execSQL(st.stocktable);
db.execSQL(bt.Brokerage);
db.execSQL(sl.Create());
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
class file:
public class SList {
Context c1;
Cursor getid;
StockList(Context mContext){
c1=mContext;
}
**//SQLiteDatabase sd=Database.getInstance(c1).getWritableDatabase();**
String Ctable;
//String ,selectIDgetstocks,deletestock;
public String tablename="Stocklist";
public String Column1="_id";
public String Column2="Sname";
ContentValues cv=new ContentValues();
String getstocks="Select " + Column1 + " as _id, " + Column2 + " From "+ tablename;
String selectID="Select Max("+ Column1 + ") from " + tablename;
public String Create(){
Ctable="Create Table " + tablename + " (" + Column1 + " INTEGER PRIMARY KEY , " + Column2 + " Text" + ")";
return Ctable;
}
public void insert(int stockid,String name){
cv.put(Column1, stockid);
cv.put(Column2, name);
++Database.getInstance(c1).getWritableDatabase().insert(tablename,null,cv);++
}
}

You should have a function to open the database, a function to close the database, and other functions to query. Consider the following class:
public void openDatabase(){
database = Database.getInstance(c1).getWritableDatabase();
}
public void closeDatabase(){
database.close()
}
public void insert(){
//your insertion code here using database object
}
public String select(){
//your selection code here using database object
}
make database class variable. This way you can call openDatabase() at first and never have to open again until you close it or instantiate the class for the first time.
Then you can use insert or select as required.
Hope this helps

I believe class Database is wrapper for SQLiteOpenHelper, right? Since you have a singleton, each time you call getWritableDatabase() it's utilizing existing connection. The new connection is being called only at the first call. You can open new connection at onResume or onCreate and close it at onDestroy or onPause, for example.
From the docs on getWritableDatabase():
Once opened successfully, the database is cached, so you can call this method every time you need to write to the database

Related

Android - What is the Best/Efficient way of converting an Encrypted database to a plain database file

I have used SQLiteCipher to add security to my application database, the problem is, it is way too slow than the default android SQLite API. So I switched back to the default SQLite API, but I really need the security provided by SQLCipher, so What I did is:
Upon opening my app
Open the encrypted database file
Create a normal database file
Transfer records from encrypted to normal database
Delete the encrypted database file
Use the normal database file
When my app is closed,
Open the normal database file
Create a encrypted database file
Transfer records from normal to encrypted database
Delete the normal database file
This works without any problems, but transferring records takes some time and will consume more(I am assuming that my database file will contain thousands of records during its real-life usage). So is there any other way of what I have done?
Are there any more efficient ways of doing this? TIA!
EDIT : Here are some code using the SQLCipher
Main Activity
private final static String phrase = "passW0rd3r";
private EditText StudNum, StudName, StudCrse;
private DBHelper dbIns;
SQLiteDatabase DBFile;
private MainDBHelper DBHelp;
private MenuItem msg_app;
final Context con = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StudNum = (EditText)findViewById(R.id.txtsNum);
StudName = (EditText)findViewById(R.id.txtsName);
StudCrse = (EditText)findViewById(R.id.txtCourse);
StudNum.requestFocus();
SQLiteDatabase.loadLibs(this);
dbIns = new DBHelper(this, DB_NAME);
DBFile = dbIns.getWritableDatabase(phrase);
DBHelp = new MainDBHelper(this);
//Takes too much time to load, loads around 3 seconds, compared to
//the default SQLite API, which is half a second only
}
MainDBHelper class
public class MainDBHelper {
private static final String DB_NAME = "StudentInfo.db";
private static final String TABLE_NAME = "StudentInfo";
private final static String phrase = "passW0rd3r";
private DBHelper openHelper;
private SQLiteDatabase database;
public MainDBHelper(Context context) {
openHelper = new DBHelper(context, DB_NAME);
database = openHelper.getWritableDatabase(phrase);
}
}
DBHelper class
public class DBHelper extends SQLiteOpenHelper{
private String DBName;
public DBHelper(Context context, String DBname) {
super(context, DBname, null, 5);
this.DBName = DBname.substring(0,DBname.length()-3);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
arg0.execSQL("CREATE TABLE " + DBName + " (_id INTEGER PRIMARY KEY, " +
"Stud_Num TEXT, Stud_Name TEXT, Stud_Crse TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
arg0.execSQL("DROP TABLE IF EXISTS " + DBName);
onCreate(arg0);
}
}
Extra class that uses the same Database Connection
DisplayMessageActivity class - this one loads around 2 seconds just to show 3 records in the list view. If I use the default SQLite API, it can load up to 10 records in just a second
public class DisplayMessageActivity extends Activity {
private ListAdapter listAdapt;
private MainDBHelper DBHelp;
private EditText edtName, edtSnum, edtCrse;
private TextView dName, dSnum, dCrse, ssn;
private ListView lst_snum;
private SearchView sView;
private MenuItem sItem;
private View lView, diagView;
private AlertDialog.Builder DBuilder;
private AlertDialog ADiag;
private String StudentNumber, edSname, edSnum, edCrse;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
DBHelp = new MainDBHelper(this);
lst_snum = (ListView)findViewById(R.id.lv_test);
refreshList();
createADiag(this);
lst_snum.setOnItemLongClickListener(new OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
lView = view;
ssn = (TextView)view.findViewById(R.id.studNum);
ADiag.show();
return false;
}
});
}
private void refreshList(){
listAdapt = null;
listAdapt = new ListAdapter(this, DBHelp.getTimeRecordList());
lst_snum.setAdapter(listAdapt);
}
}
Update: I've read some questions related to mine and I really see that some are also facing performance issues by using SQLCipher, one answer said that to "Cache the database" for one time connection only that can be used on multiple activities on the same app, problem is, I don't have any idea to do that
There are a few very important guidelines for optimal SQLCipher performance:
Do not repeatedly open and close connections, as key derivation is very expensive, by design
Use transactions to wrap insert / update / delete operations. Unless executed in a transaction scope, every operation will occur within it's own transaction which slows things down by several orders of magnitude
Ensure your data is normalized (i.e., using good practices for separation of data into multiple tables to eliminate redundancy). Unnecessary duplication of data leads to database bloat, which means more pages for SQLCipher to operate on
Ensure that any columns that are used for searches or join conditions are indexed. If you don't, SQLCipher will need to execute full database scans across large numbers of pages
Vacuum periodically to ensure databases are compact if you do large deletes, updates etc.
Finally, to diagnose further the performance of your specific query statements, there are a couple of options. First, I would recommend running PRAGMA cipher_profile as CommonsWare mentioned above, you can read more about the usage here. This will give you a log of the queries performed on the database and their respective execution times in milliseconds. Next, you run an explain query plan command against some of your queries that may be performing poorly? The output of the explain query command is described here.

how to show listview context by database

i have a listview in my project that links to database and shows its context from database but my problem is whenever my application runs it records goes twice (ex.2records first run, 4records with same context,...) and i do not know that wat is problem
this is my database class:
new File(DIR_DATABASE).mkdirs();
dataBase = SQLiteDatabase.openOrCreateDatabase(DIR_DATABASE + "/information.sqlite", null);
dataBase.execSQL("CREATE TABLE IF NOT EXISTS information (" +
"information_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE ," +
"information_title TEXT)");
dataBase.execSQL("INSERT INTO information (information_title) VALUES ('قسمت اول')");
dataBase.execSQL("INSERT INTO information (information_title) VALUES ('قسمت دوم')");
and its my main class that shows listview:
ListView lstC findViewById(R.id.lstContent);
adapter = new AdapterNote(title);
lstContent.setAdapter(adapter);
readFromDataBase();
adapter.notifyDataSetChanged();
}
private void readFromDataBase() {
Cursor cursor = G.dataBase.rawQuery("SELECT * FROM information", null);
while (cursor.moveToNext()) {
StructNote detail = new StructNote();
detail.title = cursor.getString(cursor.getColumnIndex("information_title"));
title.add(detail);
}
cursor.close();
adapter.notifyDataSetChanged();
}
You need to understand SQLiteOpenHelper for this. This is workflow issue, so it would be better you should go through some tutorial. This is a nice tutorial where you can learn the concept.
In very short i am listing few points that may be useful for you:
In your application you create a subclass of the SQLiteOpenHelper class.SQLiteOpenHelper is a helper class to manage database creation and version management. In subclass override, onCreate() and onUpgrade().
public class MySQLiteHelper extends SQLiteOpenHelper {
public void onCreate(SQLiteDatabase database) {
// create database command.
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// upgrade database command here.
}
}
Create a DAO class that will manage the interaction with the database. Your CRUD methods will go here. See DAO pattern for details. This class will centralize the access to database, hence your activity, fragment will interact with this class to perform operation. Direct access to database won't be allowed.
public class ModelDataSource {
// needed to perform operation on database
private SQLiteDatabase database;
//needed to retrieve database object
private MySQLiteHelper dbHelper;
public boolean insertModel(Model model) {
// perform insert operation on database
}
}
In your activity, you can interact with DAO to perform some action.
public class YourActivity extends Activity {
private ModelDataSource datasource;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
datasource = new ModelDataSource(this);
datasource.open();
boolean insertion_status = datasource.insert(modelobject);
}
}

Followed the official android documentations but still could not use SQLite in app

My DBHelper class
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context)
{
super(context,"SIMPLE_DB",null,1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE SIMPLE_TABLE ( " +
"ID INTEGER PRIMARY KEY " +
"DESC TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Activity class
public class SimpleDatabase extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(this);
SQLiteDatabase db = dbHelper.getReadableDatabase();
db.execSQL("INSERT INTO SIMPLE_TABLE VALUES (NULL, 'test');");
Cursor cursor = db.rawQuery("SELECT * FROM SIMPLE_TABLE", null);
TextView text = (TextView)findViewById(R.id.textbox);
text.setText(cursor.getString(0));
}
}
I figure it crashed (application has stopped unexpectedly!) at SQLiteDatabase db = ... because if I commented the code out from there to the end then it worked fine. But I have no idea whatsoever why it does that.
Any help would be appreciated.
Never mind, figured out what I did wrong now.
db.execSQL("CREATE TABLE SIMPLE_TABLE ( " + "ID INTEGER PRIMARY KEY<comma goes here> " + "DESC TEXT);");
Commas are serious businesses. Sorry for the stupid question.
first of all you should ensure that your SQL statement is correct. If sqlite3 is in your path you could execute the command:
$>: sqlite3 testdb.db
after that you are in an shell where you can test your SQL statements if there are syntactically correct. (Hint: refering the example above: it is not correct).
After that you should handle your cursor correctly as described by Aurora.
Maybe you should implement your onUpgrade() method, e.g:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS SIMPLE_TABLE");
onCreate(db);
}
First, to help in your debugging, make sure to use the debug monitor and Log. This will make your life a lot easier in the long run! If you are using Eclipse, select Window -> Open Perspective -> Other -> DDMS. The LogCat will show you what is happening as the program is run. Documentation describes it here. Run your program again and watch the LogCat. It should give you more information and tell you what line of code is crashing.
As far as your code goes, the first thing I notice is that after you get a cursor back, you need to call cursor.moveToFirst(); to select the (first) row. Then when you call cursor.getString(0);, it indicates the zeroeth column of the zeroeth row. If you do not call moveToFirst(); then you cursor.getString(0) is going to get the zeroeth column of the -1st row and be an index out of bounds error. By default, the cursor will start at row -1.
Depending on how you want to move through your cursor, and how many results/rows you get back, you may also need to call cursor.movetoPosition() or cursor.moveToNext(). Check out the documentation on cursors here.

Creating initial SQLiteDatabase when app is installed

I am writing an app that displays fun-facts (and the source they are from). The user can browse through the facts one by one.
Here is the design I thought of :
Create a table in SQLiteDatabase with a text column that stores the fun-fact and a second column that stores it's source. (not sure if this is the best way to go about doing it, but I want the app available even without the network)
My question is, when database is initially created on the device, should I manually populate the database from within the code, something like this pseodo-code:-
#Override
public void onCreate(SQLiteDatabase db) {
//Create the table
//Populate the table
//Insert statement 1
//Insert statement 2
//Insert statement 3
...
//Insert statement 500
}
Surely there must be a better method to create the initial database when the app is installed?
Are you certain that you really need a databse? Doesn't it just add unnecessary overhead to something so trivial?
Can't you just declare the array in your code, or am I missing something? Whether it's in the db or your code, it is taking up space. The db will add some overhead to that and vious?will take some time to load, plus your code has to handle errors, etc.
Woudl you not be better off with a simple array declared in your code? Or am I misisng something obvious? (maybe users can d/l a new db? But is that so much more overhead than d/ling a new program?)
If I'm way off, please explain (rather than downvoting). I am trying to help
Edit: presumably you already have your facts soemwhere? Maybe in a text file? You could just write code to parse that and initialze and array (or populate a db). It should bascially be a short for loop.
use a class derived from SQLiteOpenHelper
i already wrote sth obout this on my blog www.xenonite.net
public class myDatabase extends SQLiteOpenHelper
{
private static final String DB_NAME = "database.db";
private static final int DB_VERSION = 1;
public MyDatabase(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE tbl_test ( id INTEGER PRIMARY KEY AUTOINCREMENT, test TEXT NOT NULL )");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS tbl_test");
onCreate(db);
}
}
you can use this like
myDatabase db = new myDatabase(getApplicationContext());
sql = "INSERT INTO tbl_test (test) VALUES ('xyz')";
db.getWritableDatabase().execSQL(sql);
String sql = "SELECT id FROM tbl_test";
Cursor result = db.getWritableDatabase().rawQuery(sql, null);
int value;
while(result.moveToNext())
{
value = result.getInt(0);
}
on every call to db, myDatabase.onCreate() is called, so your database will be created on the first run. when changing the table structure, implement onUpgrade() and increment DB_VERSION

Object Oriented scope and inheritance in Android activity classes

I'm still very new to Object Oriented programming and am having problems with the class inheritance and the scope of variables from one instantiated class to another.
I'm trying to build an android application that can read multiple XML feeds and save them to the phone's SQLite database. Each feed has a different name ("news", "audio_mixes" etc.) and I want to use these names to save each feed's data into separate database tables - each one named after the feed title.
In diagrammatic terms this is what my classes look like:
(source: baroquedub.co.uk)
The Main activity displays two buttons each of which starts an activity - both of which are instances of the TitlesBrowser class. Extras are used to pass different values of the_url and the_feed_type variables.
#Override
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
this.setContentView(R.layout.main);
this.getNewsButton = (Button) findViewById(R.id.get_news_button);
this.getNewsButton.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
Intent doGetNews = new Intent(Main.this, TitlesBrowser.class);
doGetNews.putExtra("the_url", Main.this.getString(R.string.titles_url));
doGetNews.putExtra("the_feed_type", Main.this.getString(R.string.news_type_var));
startActivity(doGetNews);
}
});
this.getMixtapesButton = (Button) findViewById(R.id.get_mixtapes_button);
this.getMixtapesButton.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
Intent doGetMixtapes = new Intent(Main.this, TitlesBrowser.class);
doGetMixtapes.putExtra("the_url", Main.this.getString(R.string.titles_url));
doGetMixtapes.putExtra("the_feed_type", Main.this.getString(R.string.mixtapes_type_var));
startActivity(doGetMixtapes);
}
});
}
The TitlesBrowser class, in its onCreate method, gets the Extras and saves them to private local variables.
Intent i = getIntent();
private String theUrl = (String) i.getStringExtra("the_url");
private String theFeedType = (String) i.getStringExtra("the_feed_type");</pre>
This class does two things,
1/ it creates an instance of the DatabaseHelper class, and uses a public set method in that class to pass on the value of the locally help theFeedType variable. Having done that it queries the database for any existing data (the theFeedType is the name of each table)
db=new DatabaseHelper(this);
db.setTableName(theFeedType);
dbCursor=db.getReadableDatabase().rawQuery("SELECT _ID, id, title FROM "+theFeedType+" ORDER BY id", null);
2/ then it loads new data from the feed URL by instantiating another class HTTPRequestHelper :
HTTPRequestHelper helper = new HTTPRequestHelper(responseHandler);
helper.performPost(theUrl, theFeedType);
The HTTP requests work fine, and depending on which of the two buttons is clicked, each of the two different activities display the appropriate XML (i.e. retrieve the correct data)
- therefore I know that theUrl and theFeedType variables are local to each instance of the TitlesBrowser class.
One calls:
http://baroquedub.co.uk/get-feed.php?feed=news
and the other one:
http://baroquedub.co.uk/get-feed.php?feed=audio_mixes
The problem is with the DatabaseHelper class:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME="baroquedub.db";
private String table_name;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+ table_name + "(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id INTEGER, " +
"title TEXT, " +
"details TEXT, " +
"picture TEXT, " +
"viewed BOOLEAN DEFAULT '0' NOT NULL);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
android.util.Log.w("Baroquedub", "Upgrading database, which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS mixtapes");
onCreate(db);
}
public void setTableName(String theName){
this.table_name = theName;
}
}
I would expect it to create a new table each time it is instantiated (whether "news" or "audio_mixes" was passed from its parent TitlesBrowser class.
But it only works once - if I start the application and click on "news" a table called news is created and each time I return to that activity it successfully retrieves data from that same database.
But if I then start the other activity by clicking on the other button (i.e access the other feed) I get an SQL error telling me that a database of that name doesn't exist. In other words the onCreate db.execSQL("CREATE TABLE... method doesn't appear to get called again.
It's as if multiple copies of the DatabaseHelper class aren't being created, although there are two instances of TitlesBrowser.
--
Here's a demonstration of the problem:
http://screencast.com/t/NDFkZDFmMz
This has been really tricky to explain (especially for a newbie!!!) and I hope it makes some sense. I'd be very grateful for any help, advice or guidance.
When you instanciate a SQLiteOpenHelper class you actually access a singleton in the Activity's context. The helper decides when to call the OnCreate / onUpgrade methods - specifically, if the DB doesn't exist or is stale.
Either way, the onCreate method is not called each time you create a new instance of the class - that would really make no sense. You should put the two CREATE TABLE commands in the onCreate method.
(PS I assume the error you're getting is that a table is missing and not the entire database).
A big thank you to adamk for providing the guidance necessary to solve this, in the answer he provided.
He suggested that I add two CREATE TABLE commands in the DatabaseHelper's onCreate method (on for each of my feeds). However, I needed to abstract things a little more so that I could still use multiple instantiations of the TitlesBrowser activity and so that I wouldn't have to rewrite the helper class every time a new feed came on board.
For those interested, here's the solution I came up with.
First of all, I removed the CREATE TABLE commands in the DatabaseHelper's onCreate method. I also removed the private table_name variable (and its associated set method) and I replaced this with a public method called makeTable():
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME="baroquedub.db";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
android.util.Log.w("Baroquedub", "Upgrading database, which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS mixtapes");
onCreate(db);
}
public void makeTable(String theTableName){
SQLiteDatabase thisDB = DatabaseHelper.this.getWritableDatabase();
thisDB.execSQL("CREATE TABLE IF NOT EXISTS "+ theTableName + "(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id INTEGER, " +
"title TEXT, " +
"details TEXT, " +
"picture TEXT, " +
"viewed BOOLEAN DEFAULT '0' NOT NULL);");
}
}
In TitlesBrowser, rather than instantiating the DatabaseHelper, setting the table name and then reading in the data:
db=new DatabaseHelper(this);
db.setTableName(theFeedType);
dbCursor=db.getReadableDatabase().rawQuery("SELECT _ID, id, title FROM "+theFeedType+" ORDER BY id", null);
Instead, I reworked all this so that it would more elegantly handle the creation and loading of the database data from each table:
The database Helper is created as before,
then the new databaseLoad() method tries to read from the required table
and if it can't, it calls the DatabaseHelper's public makeTable() method,
before finally trying to load the data again:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = getIntent();
theUrl = (String) i.getStringExtra("the_url");
theFeedType = (String) i.getStringExtra("the_feed_type");
// show saved in DB
db=new DatabaseHelper(this);
databaseLoad();
}
private void databaseLoad(){
try { // table exists
dbCursor=db.getReadableDatabase()
.rawQuery("SELECT _ID, id, title FROM "+theFeedType+" ORDER BY id", null);
displayContent();
} catch (Exception e) { // table doesn't exist
db.makeTable(theFeedType);
databaseLoad(); // try again
}
}

Categories

Resources