1

我在没有崩溃的产品搜索应用程序中遇到此错误,但当我在模拟器中单击返回按钮(从项目的详细信息返回 - “DetaljiProizvoda.java”活动)时显然存在与数据库相关的问题(此时此错误出现在 Logcat 中) 我用 values.put 输入的一些新条目在我搜索它们时似乎没有出现,其他条目出现在搜索结果中。

09-05 21:01:23.082: W/IInputConnectionWrapper(758): showStatusIcon on inactive InputConnection
09-05 21:01:48.901: I/dalvikvm(813): threadid=3: reacting to signal 3
09-05 21:01:48.951: I/dalvikvm(813): Wrote stack traces to '/data/anr/traces.txt'
09-05 21:01:49.401: I/dalvikvm(813): threadid=3: reacting to signal 3
09-05 21:01:49.451: I/dalvikvm(813): Wrote stack traces to '/data/anr/traces.txt'
09-05 21:01:49.741: D/gralloc_goldfish(813): Emulator without GPU emulation detected.
09-05 21:01:49.901: I/dalvikvm(813): threadid=3: reacting to signal 3
09-05 21:01:49.951: I/dalvikvm(813): Wrote stack traces to '/data/anr/traces.txt'
09-05 21:02:06.762: I/dalvikvm(813): threadid=3: reacting to signal 3
09-05 21:02:06.781: I/dalvikvm(813): Wrote stack traces to '/data/anr/traces.txt'
09-05 21:02:28.111: D/dalvikvm(813): GC_CONCURRENT freed 143K, 3% free 9386K/9671K, paused 8ms+31ms
09-05 21:02:28.122: E/SQLiteDatabase(813): close() was never explicitly called on database '/data/data/hr.punctum.LociranjePonudaProizvoda/databases/proizvodidb' 
09-05 21:02:28.122: E/SQLiteDatabase(813): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1943)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:770)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at hr.punctum.LociranjePonudaProizvoda.DetaljiProizvoda.onCreate(DetaljiProizvoda.java:24)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.Activity.performCreate(Activity.java:4465)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.ActivityThread.access$600(ActivityThread.java:123)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.os.Handler.dispatchMessage(Handler.java:99)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.os.Looper.loop(Looper.java:137)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at android.app.ActivityThread.main(ActivityThread.java:4424)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at java.lang.reflect.Method.invokeNative(Native Method)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at java.lang.reflect.Method.invoke(Method.java:511)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-05 21:02:28.122: E/SQLiteDatabase(813):  at dalvik.system.NativeStart.main(Native Method)
09-05 21:02:28.202: E/System(813): Uncaught exception thrown by finalizer
09-05 21:02:28.332: E/System(813): java.lang.IllegalStateException: Don't have database lock!
09-05 21:02:28.332: E/System(813):  at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2090)
09-05 21:02:28.332: E/System(813):  at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2182)
09-05 21:02:28.332: E/System(813):  at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2178)
09-05 21:02:28.332: E/System(813):  at android.util.LruCache.trimToSize(LruCache.java:197)
09-05 21:02:28.332: E/System(813):  at android.util.LruCache.evictAll(LruCache.java:285)
09-05 21:02:28.332: E/System(813):  at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2143)
09-05 21:02:28.332: E/System(813):  at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
09-05 21:02:28.332: E/System(813):  at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1914)
09-05 21:02:28.332: E/System(813):  at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
09-05 21:02:28.332: E/System(813):  at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
09-05 21:02:28.332: E/System(813):  at java.lang.Thread.run(Thread.java:856)
09-05 21:02:28.511: E/SQLiteDatabase(813): close() was never explicitly called on database '/data/data/hr.punctum.LociranjePonudaProizvoda/databases/proizvodidb' 
09-05 21:02:28.511: E/SQLiteDatabase(813): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1943)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:770)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at hr.punctum.LociranjePonudaProizvoda.DetaljiProizvoda.onCreate(DetaljiProizvoda.java:24)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.Activity.performCreate(Activity.java:4465)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.ActivityThread.access$600(ActivityThread.java:123)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.os.Handler.dispatchMessage(Handler.java:99)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.os.Looper.loop(Looper.java:137)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at android.app.ActivityThread.main(ActivityThread.java:4424)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at java.lang.reflect.Method.invokeNative(Native Method)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at java.lang.reflect.Method.invoke(Method.java:511)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-05 21:02:28.511: E/SQLiteDatabase(813):  at dalvik.system.NativeStart.main(Native Method)
09-05 21:02:28.552: E/System(813): Uncaught exception thrown by finalizer
09-05 21:02:28.601: E/System(813): java.lang.IllegalStateException: Don't have database lock!
09-05 21:02:28.601: E/System(813):  at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2090)
09-05 21:02:28.601: E/System(813):  at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2182)
09-05 21:02:28.601: E/System(813):  at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2178)
09-05 21:02:28.601: E/System(813):  at android.util.LruCache.trimToSize(LruCache.java:197)
09-05 21:02:28.601: E/System(813):  at android.util.LruCache.evictAll(LruCache.java:285)
09-05 21:02:28.601: E/System(813):  at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2143)
09-05 21:02:28.601: E/System(813):  at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
09-05 21:02:28.601: E/System(813):  at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1914)
09-05 21:02:28.601: E/System(813):  at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
09-05 21:02:28.601: E/System(813):  at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
09-05 21:02:28.601: E/System(813):  at java.lang.Thread.run(Thread.java:856)

数据库助手.java

package hr.punctum.LociranjePonudaProizvoda;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

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) {
        /*
         * Kreiranje tabele proizvodi i punjenje tabele sa podacima.
         * Kasnije cu prebaciti ove hardcore kodirane statment-e u XML datoteku.
         */
        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)";
        db.execSQL(sql);

        ContentValues values = new ContentValues();

        values.put("naziv", "Canon 60D");
        values.put("tvrtka", "Protis");
        values.put("cijena", "4600");
        values.put("kategorija", "fotoaparati");
        values.put("telefonTvrtke", "016587176");
        values.put("adresaTvrtke", "Laducka 36A");
        db.insert("proizvodi", "tvrtka", values);

        values.put("naziv", "Nikon D800");
        values.put("tvrtka", "MagazinRS");
        values.put("cijena", "21600");
        values.put("kategorija", "fotoaparati");
        values.put("telefonTvrtke", "454562542");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);   

        values.put("naziv", "Olympus OM-D");
        values.put("tvrtka", "Telebit");
        values.put("cijena", "5200");
        values.put("kategorija", "fotoaparati");
        values.put("telefonTvrtke", "5657676");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);

        values.put("naziv", "Pentax K-7");
        values.put("tvrtka", "Svijet medija");
        values.put("cijena", "7400");
        values.put("kategorija", "fotoaparati");
        values.put("telefonTvrtke", "11236676");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);

        values.put("naziv", "Samsung S3");
        values.put("tvrtka", "Svijet medija");
        values.put("cijena", "4200");
        values.put("kategorija", "mobiteli");
        values.put("telefonTvrtke", "7814442222");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);

        values.put("naziv", "Samsung S2");
        values.put("tvrtka", "Svijet medija");
        values.put("cijena", "3200");
        values.put("kategorija", "mobiteli");
        values.put("telefonTvrtke", "7814442222");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);

        values.put("naziv", "Huawei U8650");
        values.put("tvrtka", "MagazinRS");
        values.put("cijena", "3200");
        values.put("kategorija", "mobiteli");
        values.put("telefonTvrtke", "7814442222");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);

        values.put("naziv", "Huawei U8660");
        values.put("tvrtka", "MagazinRS");
        values.put("cijena", "3200");
        values.put("kategorija", "mobiteli");
        values.put("telefonTvrtke", "7814442222");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);

        values.put("naziv", "Huawei U8660");
        values.put("tvrtka", "MagazinRS");
        values.put("cijena", "3400");
        values.put("kategorija", "mobiteli");
        values.put("telefonTvrtke", "7814442222");
        values.put("adresaTvrtke", "Laniste 1B");       
        db.insert("proizvodi", "tvrtka", values);

        //db.close();   
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS proizvodi");
        onCreate(db);
    }

}

ListaProizvoda.java

package hr.punctum.LociranjePonudaProizvoda;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

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) {
        // || je operacija spajanja u SQLiteu, slijedeci sql query vraca rezultat iz baze svih zapisa koji pocinju na slovo uneseno u search polje
        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});
        setListAdapter(adapter);    

    }

    public void onListItemClick(ListView parent, View view, int position, long id) {
        //kreiranje Intenta za komunikaciju s drugim activity-om
        Intent intent = new Intent(this, DetaljiProizvoda.class);
        Cursor cursor = (Cursor) adapter.getItem(position);
        //slanje varijable
        intent.putExtra("PROIZVODI_ID", cursor.getInt(cursor.getColumnIndex("_id")));
        startActivity(intent);
    }

}   

DetaljiProizvoda.java

package hr.punctum.LociranjePonudaProizvoda;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.TextView;

public class DetaljiProizvoda extends Activity {

    protected TextView naziv;
    protected TextView kategorija;
    protected TextView tvrtka;
    protected TextView telefonTvrtke;
    protected TextView adresaTvrtke;
    protected int proizvodId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.detalji_proizvoda);
        //hvatanje parametra (ID iz tablice) Intenta iz ListaProizvoda activity-a
        proizvodId = getIntent().getIntExtra("PROIZVODI_ID", 0);
        SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT proizv._id, proizv.naziv, proizv.tvrtka, proizv.cijena, proizv.kategorija, proizv.telefonTvrtke, proizv.adresaTvrtke 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"))); /*+ " " + cursor.getString(cursor.getColumnIndex("lastName")));*/

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

        }

    }

}
4

2 回答 2

1

只需关闭您的并cursors停止“数据库从未关闭”消息:dbonDestroy()

@Override
protected void onDestroy() {
    cursor.close();
    db.close();
    super.onDestroy();
}

同样id在此方法中已经引用了相应的行:

public void onListItemClick(ListView parent, View view, int position, long id) {
    //kreiranje Intenta za komunikaciju s drugim activity-om
    Intent intent = new Intent(this, DetaljiProizvoda.class);
    //slanje varijable 
    intent.putExtra("PROIZVODI_ID", id);
    startActivity(intent);
}

我希望这会有所帮助!


从评论中添加

我错过了你也在打开你的数据库DetaljiProizvoda,基本上你打电话的任何地方你getWritableDatabase()都需要在close()完成后打电话。DetaljiProizvoda您可以像这样进行设置ListaProizvoda(通过声明dbcursor作为类变量并复制onDestroy()方法)。onCreate()但是因为您只读取了一次数据库,所以只需将其添加到in的底部DetaljiProizvoda

cursor.close();
db.close();

您询问:

这些方法(onResume 和 onDestroy)不是已经在每个活动中实现了吗?

是的,这就是我们使用的原因@Override以及super当我们extend上课的时候。在我们的例子中,@Override告诉编译器使用我们的版本onCreate()onDestroy()等等,如果我们想调用父类的版本,我们使用super关键字。您不需要覆盖大多数父方法。您不需要覆盖 Activity 的onCreate(),但是如果没有您的代码,这个应用程序不会做太多事情onCreate()......

于 2012-09-05T20:05:34.950 回答
0
@SuppressWarnings("deprecation")
public void search(View view) {
    // || je operacija spajanja u SQLiteu, slijedeci sql query vraca rezultat iz baze svih zapisa koji pocinju na slovo uneseno u search polje
    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});
    setListAdapter(adapter);
    cursor.close();  // Add this line
    db.close(); // And this line as well

}
于 2012-09-05T20:09:05.163 回答