Reputation: 259
I've done app that is not crashing, but i get these errors in my logcat. They appear when i go back to first activity and choose items from listview. I tried to close cursors and database. What's going wrong?
09-25 09:13:07.609: I/dalvikvm(1013): threadid=3: reacting to signal 3
09-25 09:13:07.759: I/dalvikvm(1013): Wrote stack traces to '/data/anr/traces.txt'
09-25 09:13:08.089: I/dalvikvm(1013): threadid=3: reacting to signal 3
09-25 09:13:08.160: I/dalvikvm(1013): Wrote stack traces to '/data/anr/traces.txt'
09-25 09:13:08.579: I/dalvikvm(1013): threadid=3: reacting to signal 3
09-25 09:13:08.629: I/dalvikvm(1013): Wrote stack traces to '/data/anr/traces.txt'
09-25 09:13:23.170: D/dalvikvm(1013): GC_CONCURRENT freed 516K, 6% free 10848K/11463K, paused 27ms+14ms
09-25 09:13:23.209: E/SQLiteDatabase(1013): close() was never explicitly called on database '/data/data/hr.punctum.LociranjePonudaProizvoda/databases/proizvodidb'
09-25 09:13:23.209: E/SQLiteDatabase(1013): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1943)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:770)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at hr.punctum.LociranjePonudaProizvoda.ListaProizvoda.onCreate(ListaProizvoda.java:27)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.Activity.performCreate(Activity.java:4465)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.ActivityThread.access$600(ActivityThread.java:123)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.os.Handler.dispatchMessage(Handler.java:99)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.os.Looper.loop(Looper.java:137)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at android.app.ActivityThread.main(ActivityThread.java:4424)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at java.lang.reflect.Method.invokeNative(Native Method)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at java.lang.reflect.Method.invoke(Method.java:511)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-25 09:13:23.209: E/SQLiteDatabase(1013): at dalvik.system.NativeStart.main(Native Method)
09-25 09:13:23.230: E/System(1013): Uncaught exception thrown by finalizer
09-25 09:13:23.261: E/System(1013): java.lang.IllegalStateException: Don't have database lock!
09-25 09:13:23.261: E/System(1013): at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2090)
09-25 09:13:23.261: E/System(1013): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2182)
09-25 09:13:23.261: E/System(1013): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2178)
09-25 09:13:23.261: E/System(1013): at android.util.LruCache.trimToSize(LruCache.java:197)
09-25 09:13:23.261: E/System(1013): at android.util.LruCache.evictAll(LruCache.java:285)
09-25 09:13:23.261: E/System(1013): at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2143)
09-25 09:13:23.261: E/System(1013): at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
09-25 09:13:23.261: E/System(1013): at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1914)
09-25 09:13:23.261: E/System(1013): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
09-25 09:13:23.261: E/System(1013): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
09-25 09:13:23.261: E/System(1013): at java.lang.Thread.run(Thread.java:856)
09-25 09:13:23.390: I/dalvikvm(1013): threadid=3: reacting to signal 3
09-25 09:13:23.409: I/dalvikvm(1013): Wrote stack traces to '/data/anr/traces.txt'
DatabaseHelper.java
package hr.punctum.LociranjePonudaProizvoda;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "proizvodidb";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS proizvodi (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"naziv TEXT, " +
"tvrtka TEXT, " +
"cijena TEXT, " +
"kategorija TEXT, " +
"telefonTvrtke TEXT, " +
"adresaTvrtke TEXT, " +
"latitude INTEGER, " +
"longitude INTEGER)";
db.execSQL(sql);
ContentValues values = new ContentValues();
values.put("naziv", "Canon 5D mark III");
values.put("tvrtka", "M-Computers");
values.put("cijena", "27257kn");
values.put("kategorija", "fotoaparati");
values.put("telefonTvrtke", "01/3707800");
values.put("adresaTvrtke", "Cankareva 3, Zagreb");
values.put("latitude", 45813029);
values.put("longitude", 15977894);
db.insert("proizvodi", "tvrtka", values);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS proizvodi");
onCreate(db);
db.close();
}
ListaProizvoda.java
package hr.punctum.LociranjePonudaProizvoda;
public class ListaProizvoda extends ListActivity {
protected EditText searchText;
protected SQLiteDatabase db;
protected Cursor cursor;
protected ListAdapter adapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = (new DatabaseHelper(this)).getWritableDatabase();
searchText = (EditText) findViewById (R.id.searchText);
}
@SuppressWarnings("deprecation")
public void search(View view) {
cursor = db.rawQuery("SELECT _id, naziv, tvrtka, cijena FROM proizvodi WHERE naziv LIKE ?",
new String[]{searchText.getText().toString() + "%"});
adapter = new SimpleCursorAdapter(this,R.layout.proizvodi_list_artikl,cursor,new String[] {"naziv", "tvrtka", "cijena"},new int[] {R.id.naziv, R.id.tvrtka, R.id.cijena});
startManagingCursor(cursor);
setListAdapter(adapter);
}
public void onListItemClick(ListView parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), DetaljiProizvoda.class);
Cursor cursor = (Cursor) adapter.getItem(position);
intent.putExtra("PROIZVODI_ID", cursor.getInt(cursor.getColumnIndex("_id")));
startActivity(intent);
}
}
DetaljiProizvoda.java
package hr.punctum.LociranjePonudaProizvoda;
public class DetaljiProizvoda extends Activity {
protected TextView naziv;
protected TextView kategorija;
protected TextView tvrtka;
protected TextView telefonTvrtke;
protected TextView adresaTvrtke;
protected int proizvodId;
protected Cursor cursor;
protected ListAdapter adapter;
protected SQLiteDatabase db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detalji_proizvoda);
proizvodId = getIntent().getIntExtra("PROIZVODI_ID", 0);
db = (new DatabaseHelper(this)).getWritableDatabase();
cursor = db.rawQuery("SELECT proizv._id, proizv.naziv, proizv.tvrtka, proizv.cijena, proizv.kategorija, proizv.telefonTvrtke, proizv.adresaTvrtke, proizv.latitude, proizv.longitude FROM proizvodi proizv LEFT OUTER JOIN proizvodi mgr ON proizv._id = mgr._id WHERE proizv._id = ?",
new String[]{""+proizvodId});
if (cursor.getCount() == 1)
{
cursor.moveToFirst();
naziv = (TextView) findViewById(R.id.naziv);
naziv.setText(cursor.getString(cursor.getColumnIndex("naziv")));
kategorija = (TextView) findViewById(R.id.kategorija);
kategorija.setText(cursor.getString(cursor.getColumnIndex("kategorija")));
tvrtka = (TextView) findViewById(R.id.tvrtka);
tvrtka.setText(cursor.getString(cursor.getColumnIndex("tvrtka")));
telefonTvrtke = (TextView) findViewById(R.id.telefonTvrtke);
telefonTvrtke.setText(cursor.getString(cursor.getColumnIndex("telefonTvrtke")));
adresaTvrtke = (TextView) findViewById(R.id.adresaTvrtke);
adresaTvrtke.setText(cursor.getString(cursor.getColumnIndex("adresaTvrtke")));
}
}
public void changeActivity(View view) {
Intent intent = new Intent(getApplicationContext(), GMapsActivity.class);
intent.putExtra("PROIZVODI_ID", cursor.getColumnIndex("_id"));
intent.putExtra("PROIZVODI_LATITUDE", cursor.getInt(cursor.getColumnIndex("latitude")));
intent.putExtra("PROIZVODI_LONGITUDE", cursor.getInt(cursor.getColumnIndex("longitude")));
startActivity(intent);
cursor.close();
db.close();
}
}
Upvotes: 0
Views: 4921
Reputation: 9507
You should forgot database.close()
. Please varify all database.open() in your cases and close database after you successfully operate it..
Upvotes: 1
Reputation: 4784
You would be better off making your DatabaseHelper into a singleton and keeping it open for the lifetime of the app:-
DatabaseHelper helper = DatabaseHelper.getInstance();
This is a common approach since you never have to close your database explicitly and since Android is a single user environment, its uncessessary to open and close the database frequently.
ContentProvider implementations are persisted as singletons and its common to create an field instance of your SqliteOpenHelper in the providers onCreate(...), you can see an example of it here http://developer.android.com/guide/topics/providers/content-provider-creating.html
So however you decide to manage your databases lifecycle, consider holding a single instance somewhere to save you some trouble, especially when you start using it across threads.
Upvotes: 1
Reputation: 1584
close your database on onStop()
or onDestroy()
method of your activity.
Upvotes: 3
Reputation: 21191
close the database when in onDestroy
of your activity
protected void onDestroy()
{
super.onDestroy();
if (db != null)
{
db.close();
}
}
and also add close method in datahelper class as
public void close() {
// NOTE: openHelper must now be a member of CallDataHelper;
// you currently have it as a local in your constructor
if (openHelper != null) {
openHelper.close();
}
}
Upvotes: 0