【问题标题】:What is a Full Android Database Helper class for an existing SQLite database? [closed]什么是现有 SQLite 数据库的完整 Android 数据库助手类? [关闭]
【发布时间】:2011-04-02 16:32:06
【问题描述】:

我正在尝试使用现有 SQLite 数据库部署应用程序。

我已通读并尝试在线实现几个示例,但我发现它们总是缺少一些代码,要么无法编译,要么无法像宣传的那样工作。

有没有人有完整的 Android Database Helper 类来在 Android 上部署现有的 SQLite 数据库?

【问题讨论】:

  • 我试过使用你的代码,但它卡在这部分:ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.mdegges/.MicheleActivity。永远不会创建 data/data/com.mdegges/database 文件。
  • @mdegges 我不确定那里出了什么问题。从您的其他问题来看,您似乎也陷入了 LAUNCHER 部分。你能在包含 db 代码之前执行一个 hello world 测试吗?
  • 是的,我已经能够在开发网站上完成大量的 tuts(包括 hello world)。奇怪的是,我尝试过的任何指南都没有奏效。数据库在我的资产文件夹中,我将 DB_PATH 更改为正确的输出文件夹,并将数据库名称更改为我的数据库(带和不带扩展名),但是不走运!
  • 我能够让它工作。 :)
  • 这基本上是在问“给我一个 SQLLite 的数据库助手类”,并且符合“过于宽泛”的定义。我没有投反对票,我关闭这个问题。在 NARQ 下关闭的问题会在关闭后自动获得 -1 票。答案很好,但问题本身很糟糕,需要大量工作。提出和回答您自己的问题是可以的(甚至是鼓励的),但这让您有双重责任,即提供一个高质量的答案一个高质量的问题。

标签: android database sqlite installation


【解决方案1】:
DatabaseHelper dbHelper = new DatabaseHelper(getApplicationContext());

确保在应用程序生命周期内创建一次 DatabaseHelper 对象并重用它。

读取数据:

SQLiteDatabase db = dbHelper.getReadableDatabase();

用于读取/修改数据:

SQLiteDatabase db = dbHelper.getWritableDatabase();

接下来使用 SQLiteDatabase 对象的insert()query()update()delete() 方法:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

您也不应该像在 createNewDatabase 方法中那样直接访问 sqlite 文件来创建数据库。 在 onCreate(...) 方法中使用 SQLiteDatabase 对象的 execSQL() 方法。在那里执行您的 CREATE TABLE 查询。

【讨论】:

  • 嗨 radek-k,你能扩展你的第一点吗? Make sure you create DatabaseHelper object once during application lifetime and reuse it.
  • 如果您多次创建 DatabaseHelper 对象,请确保您之前关闭了数据库 - getWritableDatabase.close()。在多线程应用程序模型中,当您没有关闭前一个时,您无法重新创建 DatabaseHelper。你只会得到一些例外。最好的方法是只创建一次 DatabaseHelper 对象(例如在 Application 中)并始终使用相同的对象引用。
  • 我不推荐使用getApplicationContext()。改用这个,因为任何响应 getApplicationContext() 的都是 Context
  • 您可以在ActivityApplication 中使用this。 Commonsware 和我都是对的。只需查看 api 文档并传递任何扩展 android.content.Context 的内容。 developer.android.com/reference/android/database/sqlite/…
【解决方案2】:

这是我想出的,希望它可以帮助其他遇到麻烦的人。

package com.MyPackage;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class AnyDBAdapter {

    private static final String TAG = "AnyDBAdapter";
    private DatabaseHelper mDbHelper;
    private static SQLiteDatabase mDb;

    //make sure this matches the 
    //package com.MyPackage;
    //at the top of this file
    private static String DB_PATH = "/data/data/com.MyPackage/databases/";

    //make sure this matches your database name in your assets folder
    // my database file does not have an extension on it 
    // if yours does
    // add the extention
    private static final String DATABASE_NAME = "data";

    //Im using an sqlite3 database, I have no clue if this makes a difference or not
    private static final int DATABASE_VERSION = 3;

    private final Context adapterContext;

    public AnyDBAdapter(Context context) {
        this.adapterContext = context;
    }

    public AnyDBAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(adapterContext);

        try {
            mDbHelper.createDataBase();
        } catch (IOException ioe) {
            throw new Error("Unable to create database");
        }

        try {
            mDbHelper.openDataBase();
        } catch (SQLException sqle) {
            throw sqle;
        }
        return this;
    }
    //Usage from outside
    // AnyDBAdapter dba = new AnyDBAdapter(contextObject); //in my case contextObject is a Map
    // dba.open();
    // Cursor c = dba.ExampleSelect("Rawr!");
    // contextObject.startManagingCursor(c);
    // String s1 = "", s2 = "";
    // if(c.moveToFirst())
    // do {
    //  s1 = c.getString(0);
    //  s2 = c.getString(1);
    //  } while (c.moveToNext());
    // dba.close();
    public Cursor ExampleSelect(string myVariable)
    {
        String query = "SELECT locale, ? FROM android_metadata";
        return mDb.rawQuery(query, new String[]{myVariable});
    }

    //Usage
    // AnyDBAdatper dba = new AnyDBAdapter(contextObjecT);
    // dba.open();
    // dba.ExampleCommand("en-CA", "en-GB");
    // dba.close();
    public void ExampleCommand(String myVariable1, String myVariable2)
    {
        String command = "INSERT INTO android_metadata (locale) SELECT ? UNION ALL SELECT ?";
        mDb.execSQL(command, new String[]{ myVariable1, myVariable2});
    }

    public void close() {
        mDbHelper.close();
    }

    private static class DatabaseHelper extends SQLiteOpenHelper {

        Context helperContext;

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            helperContext = context;
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database!!!!!");
            //db.execSQL("");
            onCreate(db);
        }

        public void createDataBase() throws IOException {
            boolean dbExist = checkDataBase();
            if (dbExist) {
            } else {

                //make sure your database has this table already created in it
                //this does not actually work here
                /*
                 * db.execSQL("CREATE TABLE IF NOT EXISTS \"android_metadata\" (\"locale\" TEXT DEFAULT 'en_US')"
                 * );
                 * db.execSQL("INSERT INTO \"android_metadata\" VALUES ('en_US')"
                 * );
                 */
                this.getReadableDatabase();
                try {
                    copyDataBase();
                } catch (IOException e) {
                    throw new Error("Error copying database");
                }
            }
        }

        public SQLiteDatabase getDatabase() {
            String myPath = DB_PATH + DATABASE_NAME;
            return SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        }

        private boolean checkDataBase() {
            SQLiteDatabase checkDB = null;
            try {
                String myPath = DB_PATH + DATABASE_NAME;
                checkDB = SQLiteDatabase.openDatabase(myPath, null,
                        SQLiteDatabase.OPEN_READONLY);
            } catch (SQLiteException e) {
            }
            if (checkDB != null) {
                checkDB.close();
            }
            return checkDB != null ? true : false;
        }

        private void copyDataBase() throws IOException {

            // Open your local db as the input stream
            InputStream myInput = helperContext.getAssets().open(DATABASE_NAME);

            // Path to the just created empty db
            String outFileName = DB_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);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();
        }

        public void openDataBase() throws SQLException {
            // Open the database
            String myPath = DB_PATH + DATABASE_NAME;
            mDb = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READWRITE);
        }

        @Override
        public synchronized void close() {

            if (mDb != null)
                mDb.close();

            super.close();

        }
    }

}

【讨论】:

  • 通过你的班级,是否可以打开驻留在 SD 卡上的数据库?
  • 如果您有一个现有的数据库并将自己复制到 SD 卡中,我想您可以尝试删除 copyDataBase() 调用并将 DB_PATH 更改为适当的位置。但这只是一个猜测。我不想让用户直接访问应用数据,所以我从未考虑过这个选项。
  • 看起来像是我的错字。我将代码更正为helperContext。很好的收获:)
  • 我对注释的示例行 AnyDBAdapter dba = new AnyDBAdapter(contextObject); 也有点迷失,我可以使用它来将结果放入 List 或 ArrayList 中吗?我不知道我需要为 contextObject 使用什么
  • 数据库版本“DATABASE_VERSION”是您开发的数据库的当前版本。所以如果您使用第一个版本的应用程序数据库应该有V1,如果您将应用程序更新到版本2并更新数据库也是,数据库版本应该有 v2 等等..这个标志用于跟踪数据库更新,如果 android 检测到数据库版本增加,它会调用一个 onUpdate() 方法,可以让你备份当前数据库已存储在用户手机上,因此不会被删除并替换为新数据库...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 2014-11-30
  • 2014-12-02
  • 2016-12-23
  • 1970-01-01
相关资源
最近更新 更多