/i am writing probgram that should take xml file and parse it to database. Database worked witohut crashes, but with close() error, before i tried to implement update function, after that program alwayes crashes.
i decided to use update to prevent dublication and update records ^_^ (is there better way?)
bedies i have only one activity, using clothing database onDestroy does not help. And appiared Fatal exeption ( full logcat in the bottom)
Unable to start activity ComponentInfo{com.s1042512.electionvoter/com.s1042512.electionvoter.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
main class
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.s1042512.electionvoter.ImageLoader;
import com.s1042512.electionvoter.XMLParser;
import com.s1042512.electionvoter.Candidate;
import com.s1042512.electionvoter.DatabaseHandler;
import com.s1042512.electionvoter.R;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.ImageView;
public class MainActivity extends Activity {
static final String URL = "http://www.inf.ed.ac.uk/teaching/courses/selp/elections/election.xml";
// XML node keys
static final String KEY_CANDIDATE = "candidate"; // parent node
static final String KEY_PHOTO = "photograph";
static final String KEY_NAME = "name";
static final String KEY_OFFICE = "office";
static final String KEY_PROMISES = "promise";
static final String KEY_STAT = "statement";
private DatabaseHandler db;
public void onDestroy(){
db.close();
super.onDestroy();
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DatabaseHandler(this);
Candidate test = new Candidate("Test", "Test's office", "Test's photo", "Test's promises", "Test's statement", 1,5);
db.addCandidate(test);
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_CANDIDATE);
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
NodeList prm = null;
String prom = "";
prm = doc.getElementsByTagName("promise");
if (db.getCandidatesCount() != 0) {
List<Candidate> clist = db.getAllCandidates();
boolean checkname = clist.contains(db.getCandidate(parser
.getValue(e, KEY_NAME)));
for (int j = 0; j < prm.getLength(); j++) {
prom += parser.getValue(e, KEY_PROMISES, j) + "\n";
}
if (!checkname) {
Log.d("Insert: ", "Inserting ..");
db.addCandidate(new Candidate(parser.getValue(e, KEY_NAME),
parser.getValue(e, KEY_OFFICE), parser.getValue(e,
KEY_PHOTO), prom, parser.getValue(e,
KEY_STAT)));
} else {
Log.d("Update: ", "Updating candidate ");
Candidate cand = db.getCandidate(parser.getValue(e,
KEY_NAME));
Candidate update_cand = new Candidate(parser.getValue(e,
KEY_NAME), parser.getValue(e, KEY_OFFICE),
parser.getValue(e, KEY_PHOTO), prom,
parser.getValue(e, KEY_STAT), cand.get_active(),
cand.get_ranking());
db.updateCandidate(update_cand);
}
}
else{
Log.d("Insert: ", "Inserting ..");
db.addCandidate(new Candidate(parser.getValue(e, KEY_NAME),
parser.getValue(e, KEY_OFFICE), parser.getValue(e,
KEY_PHOTO), prom, parser.getValue(e,
KEY_STAT)));
}
}
Log.d("Reading: ", "Reading all candidates..");
List<Candidate> candidates = db.getAllCandidates();
for (Candidate cn : candidates) {
String log = "Name: "+cn.get_name()+" ,Office: " + cn.get_office() + " , Photo: " + cn.get_photograph()
+ " , Promisses: " + cn.get_promises()+ " , Statment: " + cn.get_statment();
// Writing Candidates to log
Log.d("Name: ", log);
}
}
}
helper class
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "ElectionCandidates";
// Candidates table name
private static final String TABLE_CANDIDATES = "candidates";
// Candidates Table Columns names
private static final String KEY_NAME = "name";
private static final String KEY_OFFICE = "office";
private static final String KEY_PHOTO = "photograph";
private static final String KEY_PROMISSES = "promisses";
private static final String KEY_STATMENT = "statment";
private static final String KEY_ACTIVE = "active";
private static final String KEY_RANKING = "ranking";
private SQLiteDatabase db;
private Cursor cursor;
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CANDIDATES_TABLE = "CREATE TABLE " + TABLE_CANDIDATES
+ "(" + KEY_NAME + " TEXT," + KEY_OFFICE + " TEXT," + KEY_PHOTO
+ " TEXT," + KEY_PROMISSES + " TEXT," + KEY_STATMENT + " TEXT,"
+ KEY_ACTIVE + " TEXT," + KEY_RANKING + " TEXT" + ")";
db.execSQL(CREATE_CANDIDATES_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_CANDIDATES);
// Create tables again
onCreate(db);
}
void addCandidate(Candidate candidate) {
db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, candidate.get_name()); // Candidate Name
values.put(KEY_OFFICE, candidate.get_office()); // Candidate Phone
values.put(KEY_PHOTO, candidate.get_photograph());
values.put(KEY_PROMISSES, candidate.get_promises());
values.put(KEY_STATMENT, candidate.get_statment());
values.put(KEY_ACTIVE, 1);
values.put(KEY_RANKING, 0);
// Inserting Row
db.insert(TABLE_CANDIDATES, null, values);
db.close(); // Closing database connection
}
Candidate getCandidate(String name) {
db = this.getReadableDatabase();
cursor = db.query(TABLE_CANDIDATES,
new String[] { KEY_NAME, KEY_OFFICE, KEY_PHOTO, KEY_PROMISSES,
KEY_STATMENT, KEY_ACTIVE, KEY_RANKING }, KEY_NAME + "=?",
new String[] { String.valueOf(name) }, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Candidate candidate = new Candidate(cursor.getString(0),
cursor.getString(1), cursor.getString(2), cursor.getString(3),
cursor.getString(4), Integer.parseInt(cursor.getString(5)), Integer.parseInt(cursor.getString(6)));
// return candidate
db.close();
cursor.close();
return candidate;
}
public List<Candidate> getAllCandidates() {
List<Candidate> candidateList = new ArrayList<Candidate>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_CANDIDATES;
db = this.getReadableDatabase();
cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Candidate candidate = new Candidate();
candidate.set_name(cursor.getString(0));
candidate.set_office(cursor.getString(1));
candidate.set_photograph(cursor.getString(2));
candidate.set_promises(cursor.getString(3));
candidate.set_statment(cursor.getString(4));
candidate.set_active(Integer.parseInt(cursor.getString(5)));
candidate.set_ranking(Integer.parseInt(cursor.getString(6)));
// Adding candidate to list
candidateList.add(candidate);
} while (cursor.moveToNext());
}
// return candidate list
db.close();
cursor.close();
return candidateList;
}
public int updateCandidate(Candidate candidate) {
db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, candidate.get_name()); // Candidate Name
values.put(KEY_OFFICE, candidate.get_office()); // Candidate Phone
values.put(KEY_PHOTO, candidate.get_photograph());
values.put(KEY_PROMISSES, candidate.get_promises());
values.put(KEY_STATMENT, candidate.get_statment());
values.put(KEY_ACTIVE, candidate.get_active());
values.put(KEY_RANKING, candidate.get_active());
// updating row
return db.update(TABLE_CANDIDATES, values, KEY_NAME + " = ?",
new String[] { String.valueOf(candidate.get_name()) });
}
// Deleting single candidate
public void deleteCandidate(Candidate candidate) {
db = this.getWritableDatabase();
db.delete(TABLE_CANDIDATES, KEY_NAME + " = ?",
new String[] { String.valueOf(candidate.get_name()) });
db.close();
}
// Getting candidates Count
public int getCandidatesCount() {
String countQuery = "SELECT * FROM " + TABLE_CANDIDATES;
db = this.getReadableDatabase();
cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
db.close();
// return count
return count;
}
}
logcat output
12-13 01:36:25.359: D/I was there(338): parsing
12-13 01:36:25.428: D/AndroidRuntime(338): Shutting down VM
12-13 01:36:25.428: W/dalvikvm(338): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
12-13 01:36:25.479: D/dalvikvm(338): GC_FOR_MALLOC freed 3868 objects / 251528 bytes in 53ms
12-13 01:36:25.488: E/Cursor(338): Finalizing a Cursor that has not been deactivated or closed. database = /data/data/com.s1042512.electionvoter/databases/ElectionCandidates, table = candidates, query = SELECT name, office, photograph, promisses, statment, active, ranking FROM candidates WHERE name=?
12-13 01:36:25.488: E/Cursor(338): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
12-13 01:36:25.488: E/Cursor(338): at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210)
12-13 01:36:25.488: E/Cursor(338): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
12-13 01:36:25.488: E/Cursor(338): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
12-13 01:36:25.488: E/Cursor(338): at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229)
12-13 01:36:25.488: E/Cursor(338): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
12-13 01:36:25.488: E/Cursor(338): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264)
12-13 01:36:25.488: E/Cursor(338): at com.s1042512.electionvoter.DatabaseHandler.getCandidate(DatabaseHandler.java:80)
12-13 01:36:25.488: E/Cursor(338): at com.s1042512.electionvoter.MainActivity.onCreate(MainActivity.java:58)
12-13 01:36:25.488: E/Cursor(338): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-13 01:36:25.488: E/Cursor(338): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
12-13 01:36:25.488: E/Cursor(338): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
12-13 01:36:25.488: E/Cursor(338): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
12-13 01:36:25.488: E/Cursor(338): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
12-13 01:36:25.488: E/Cursor(338): at android.os.Handler.dispatchMessage(Handler.java:99)
12-13 01:36:25.488: E/Cursor(338): at android.os.Looper.loop(Looper.java:123)
12-13 01:36:25.488: E/Cursor(338): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-13 01:36:25.488: E/Cursor(338): at java.lang.reflect.Method.invokeNative(Native Method)
12-13 01:36:25.488: E/Cursor(338): at java.lang.reflect.Method.invoke(Method.java:521)
12-13 01:36:25.488: E/Cursor(338): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-13 01:36:25.488: E/Cursor(338): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-13 01:36:25.488: E/Cursor(338): at dalvik.system.NativeStart.main(Native Method)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: SELECT name, office, photograph, promisses, statment, active, ranking FROM candidates WHERE name=?
12-13 01:36:25.508: W/SQLiteCompiledSql(338): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at com.s1042512.electionvoter.DatabaseHandler.getCandidate(DatabaseHandler.java:80)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at com.s1042512.electionvoter.MainActivity.onCreate(MainActivity.java:58)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.os.Handler.dispatchMessage(Handler.java:99)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.os.Looper.loop(Looper.java:123)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at java.lang.reflect.Method.invokeNative(Native Method)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at java.lang.reflect.Method.invoke(Method.java:521)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-13 01:36:25.508: W/SQLiteCompiledSql(338): at dalvik.system.NativeStart.main(Native Method)
12-13 01:36:25.518: E/AndroidRuntime(338): FATAL EXCEPTION: main
12-13 01:36:25.518: E/AndroidRuntime(338): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.s1042512.electionvoter/com.s1042512.electionvoter.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
12-13 01:36:25.518: E/AndroidRuntime(338): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.os.Handler.dispatchMessage(Handler.java:99)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.os.Looper.loop(Looper.java:123)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-13 01:36:25.518: E/AndroidRuntime(338): at java.lang.reflect.Method.invokeNative(Native Method)
12-13 01:36:25.518: E/AndroidRuntime(338): at java.lang.reflect.Method.invoke(Method.java:521)
12-13 01:36:25.518: E/AndroidRuntime(338): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-13 01:36:25.518: E/AndroidRuntime(338): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-13 01:36:25.518: E/AndroidRuntime(338): at dalvik.system.NativeStart.main(Native Method)
12-13 01:36:25.518: E/AndroidRuntime(338): Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
12-13 01:36:25.518: E/AndroidRuntime(338): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
12-13 01:36:25.518: E/AndroidRuntime(338): at com.s1042512.electionvoter.DatabaseHandler.getCandidate(DatabaseHandler.java:87)
12-13 01:36:25.518: E/AndroidRuntime(338): at com.s1042512.electionvoter.MainActivity.onCreate(MainActivity.java:58)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-13 01:36:25.518: E/AndroidRuntime(338): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
12-13 01:36:25.518: E/AndroidRuntime(338): ... 11 more
12-13 01:36:25.529: E/Database(338): close() was never explicitly called on database '/data/data/com.s1042512.electionvoter/databases/ElectionCandidates'
12-13 01:36:25.529: E/Database(338): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
12-13 01:36:25.529: E/Database(338): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
12-13 01:36:25.529: E/Database(338): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
12-13 01:36:25.529: E/Database(338): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
12-13 01:36:25.529: E/Database(338): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
12-13 01:36:25.529: E/Database(338): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
12-13 01:36:25.529: E/Database(338): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
12-13 01:36:25.529: E/Database(338): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
12-13 01:36:25.529: E/Database(338): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)
12-13 01:36:25.529: E/Database(338): at com.s1042512.electionvoter.DatabaseHandler.getCandidate(DatabaseHandler.java:78)
12-13 01:36:25.529: E/Database(338): at com.s1042512.electionvoter.MainActivity.onCreate(MainActivity.java:58)
12-13 01:36:25.529: E/Database(338): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-13 01:36:25.529: E/Database(338): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
12-13 01:36:25.529: E/Database(338): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
12-13 01:36:25.529: E/Database(338): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
12-13 01:36:25.529: E/Database(338): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
12-13 01:36:25.529: E/Database(338): at android.os.Handler.dispatchMessage(Handler.java:99)
12-13 01:36:25.529: E/Database(338): at android.os.Looper.loop(Looper.java:123)
12-13 01:36:25.529: E/Database(338): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-13 01:36:25.529: E/Database(338): at java.lang.reflect.Method.invokeNative(Native Method)
12-13 01:36:25.529: E/Database(338): at java.lang.reflect.Method.invoke(Method.java:521)
12-13 01:36:25.529: E/Database(338): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-13 01:36:25.529: E/Database(338): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-13 01:36:25.529: E/Database(338): at dalvik.system.NativeStart.main(Native Method)