【问题标题】:Not able to fetch data from Sqlite Database无法从 Sqlite 数据库中获取数据
【发布时间】:2012-01-06 07:23:14
【问题描述】:

我想从 SQLITE 数据库中获取数据并将其显示在一个 LIST 中。

我的数据库名称是 AppDB.db,表名称是 Scrip,其中包含 3 列 _id(主键)和 symbol&company_name,它们是文本。

我只想获取第 2 列和第 3 列。我已将数据库复制到 Assets 文件夹中。

当我执行以下代码时,我强制关闭,但我不知道可能是什么原因。请帮忙..

我是 Android 的绝对初学者,因此感谢您的帮助...

内容:

1.) DataAttach.java

2.) DbManager.java

3.) LogCat

4.) .xml 简介

5.) AVD 问题

6.) 数据库快照


1.) DataAttach.java

public class DataAttach extends Activity {
    private DbManager dbM;
    private Cursor c;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            dbM = new DbManager(this);
            dbM.createDataBase();
            dbM.openDB();

            try {
                c = dbM.fetchAllData();
            } catch (Exception e) {
                throw new Error("\n\nERROR Fetchin data\n\n");
            }

            if (c != null) {
                SimpleCursorAdapter adapter = new SimpleCursorAdapter(
                        this,
                        android.R.layout.simple_list_item_1,
                        c,
                        new String[] { c.getString(c.getColumnIndex("_id")),
                                c.getString(c.getColumnIndex("symbol")),
                                c.getString(c.getColumnIndex("company_name")) },
                        new int[] { R.id._id, R.id.symbol, R.id.company_name });
                ListView list = (ListView) findViewById(R.id.MainLayout);
                list.setAdapter(adapter);
            }
        }

        catch (Exception e) {
            throw new Error("\n\nERROR DB failure\n\n");
        }

        finally {
            c.close();
            dbM.close();
        }
    }
}     

2.) DbManager.java

public class DbManager extends SQLiteOpenHelper {

    private static final String KEY_ROWID = "_id";
    private static final String KEY_SYMBOL = "symbol";
    private static final String KEY_COMPANY_NAME = "company_name";

    private static final String DATABASE_NAME = "AppDB";
    private static final String DATABASE_PATH = "/data/data/com.dbexample/databases/";
    private static final Integer DATABASE_VERSION = 3;
    private static final String DATABASE_TABLE = "Scrip";
    // private static final String TAG = "DbManager";
    private final Context ctx;
    private SQLiteDatabase mDb;

    public DbManager(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.ctx = context;
    }

    /*
     * Creates a empty database on the system and rewrites it with your own
     * database.
     */
    public void createDataBase() {

        if (checkDataBase()) {
            // do nothing - database already exist
        } else {
            /*
             * By calling this method and empty database will be created into
             * the default system path of your application so we can overwrite
             * that database with our database.
             */
            this.getReadableDatabase();

            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("\n\nERROR copying database\n\n");
            }
        }
    }

    /*
     * Check if the database already exist to avoid re-copying the file each
     * time you open the application.
     */
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DATABASE_PATH + DATABASE_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);

        } catch (SQLiteException e) {
            throw new Error("\n\nERROR database does't exist yet\n\n");
        }

        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    /*
     * Copies your DB from your local assets-folder to the just created empty DB
     * in the system folder, from where it can be accessed and handled.
     */
    private void copyDataBase() throws IOException {
        /* Open your local db as the input stream */
        InputStream myInput = ctx.getAssets().open(DATABASE_NAME);

        /* Path to the just created empty db */
        String outFileName = DATABASE_PATH + DATABASE_NAME;

        /* Open the empty db as the output stream */
        OutputStream myOutput = new FileOutputStream(outFileName);

        /* transfer bytes from the inputfile to the outputfile */
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    public void openDB() throws SQLException {
        String myPath = DATABASE_PATH + DATABASE_NAME;
        mDb = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    }

    @Override
    public void close() {
        mDb.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }

    public Cursor fetchAllData() {
        return mDb.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_SYMBOL,
                KEY_COMPANY_NAME }, null, null, null, null, null);

        // return mDb.rawQuery("select _id,symbol,company_name from Scrip",
        // new String[] { KEY_ROWID,KEY_SYMBOL, KEY_COMPANY_NAME });
    }
}                                

3.) 记录猫

sqlite3_open_v2("/data/data/com.dbexample/databases/AppDB", &handle, 1, NULL) failed

Failed to open the database. closing it.
    
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file
    
at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
    
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1017)              

4.) Main.xml

它包含RelativeLayout,在RelativeLayout中有3个TextView。


5.) 我总是遇到这个错误

即使在重新打开 eclipse、重新启动系统、重新创建 AVD、尝试、kill_server 和 start_server 之后,我也会收到此消息。

Failed to install DataAttach.apk on device 'emulator-5554': device not found
com.android.ddmlib.InstallException: device not found
Launch canceled!            

6.) 数据库截图:

整个文档已编辑为最新的代码和 ACC。根据您的建议,但应用程序仍然无法正常工作。

【问题讨论】:

  • SimpleCursorAdapter 总是需要 _id。所以尝试在光标中也获取 _id。
  • @Hiral - 尝试过,但同样的问题 :(
  • 但是问题可能还有其他问题,包括这个..bcz 你总是需要将 _id 传递给 SimpleCursorAdapter。
  • 同意。尝试关闭未关闭的游标。但这也没有用。顺便说一句,Thnx !!
  • 整个文档编辑为最新的代码和 ACC。根据您的建议,但应用程序仍然无法正常工作。

标签: android sqlite sqlexception


【解决方案1】:

我不知道你想用这个函数做什么。您正在尝试读取 .db 文件并说数据库已创建。第一次尝试运行时,数据库路径中不会有 .db 文件。这就是抛出“没有这样的文件或目录”错误的原因。

11-25 12:06:13.398: E/Netd(31): Unable to bind netlink socket: No such file or directory

在 DBManager 构造函数中调用 SQLiteOpenHelper 的 getReadableDatabase() 如果没有,它将创建一个数据库。 SQLiteOpenHelper

 public void createNewDatabase() {
                InputStream assetsDB = null;
                try {
                    assetsDB = context.getAssets().open(DATABASE_NAME);
                    OutputStream dbOut = new FileOutputStream(DATABASE_PATH
                            + DATABASE_NAME);

                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = assetsDB.read(buffer)) > 0) {
                        dbOut.write(buffer, 0, length);
                    }

                    dbOut.flush();
                    dbOut.close();
                    assetsDB.close();
                    Log.i(TAG, "New database created...");
                } catch (IOException e) {

                    Log.e(TAG, "Could not create new database...");
                }
            }

【讨论】:

  • 是的。尝试在构造函数中调用 getReadableDatabase() 方法。希望它会工作
  • 你在构造函数中有它。无论如何,您的开放方法是非静态方法。所以你肯定会创建一个对象来调用它。在构造函数中有语句会很好
  • 我应该在之前的评论中提到这一点。你根本不需要 open 方法。只需在构造函数中使用 getReadableDatabase() ,如果它不存在,它将创建一个数据库。如果已经存在,请打开它。使用该实例来执行所有与您的数据库相关的功能
  • 希望你在命令提示符下尝试过 adb -devices 命令?是否能够找到 emulator-5554。如果能够找到,请尝试通过命令提示符手动安装 apk。
  • 我犯的 愚蠢 错误是手动创建 /data/data/com.dbexample/databases/ 目录并将我的数据库放入其中。实际上我应该将我的数据库直接复制到资产文件夹中。
【解决方案2】:

我认为,您需要将布局文件设置为:

SimpleCursorAdapter sca=new SimpleCursorAdapter(context, android.R.layout.simple_list_item_1, c, from, to);

因为您正在传递 R.layout.main,这会导致您在重新加载相同的布局文件时出错。

我不确定,但这可能是问题所在。 还要在传递给适配器的光标中添加 _id。

【讨论】:

  • 整个文档编辑为最新的代码和 ACC。根据您的建议,但应用程序仍然无法正常工作。
  • @GAMA:抱歉……我不知道! :(
【解决方案3】:

SimpleCursorAdapter 需要 _id 字段中的 Cursor 你传递给它。所以试着像这样改变你的查询:

return mDb.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_SYMBOL, KEY_COMPANY_NAME }, null, null, null, null, null);

你还得到:

android.database.sqlite.DatabaseObjectNotClosedException:应用程序 没有关闭此处打开的游标或数据库对象

确保在使用完所有Cursor 对象后调用close()

【讨论】:

  • 关闭游标并传递ID后,仍然给出相同的概率。无论如何,谢谢!
  • 整个文档编辑为最新的代码和 ACC。根据您的建议,但应用程序仍然无法正常工作。
猜你喜欢
  • 2018-05-28
  • 1970-01-01
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
相关资源
最近更新 更多