【问题标题】:Database file is not copying from assets to data/data/<package name>/databases数据库文件未从资产复制到 data/data/<package name>/databases
【发布时间】:2014-02-27 08:09:53
【问题描述】:

有很多与此问题相关的问题,但没有一个对我有帮助。如果我看到我的代码的逻辑,它应该可以工作,但仍然不能工作。我在我之前的项目中做过这个,当时它工作得很好,但现在不行。

安装应用程序时,数据库文件位于 /data/data//databases/ 路径中。但是说错误:(1)没有这样的表:表名。然后我使用 SQLite 浏览器打开数据库文件,我可以看到只有一个表 android_metadata。其他表丢失。它清除说明数据库尚未从资产文件夹中复制。相反,它在给定路径中创建新数据库。如果给定的路径在 SDCard 中,那么我的手机上没有 SD 卡,并且我的手机已植根。每次第一次安装应用程序时,我需要更改data/data//databases/目录的权限才能看到数据库的数据。

但是当我将数据库文件从资产文件夹动态拉到 /data/data//databases/ 时,我的应用程序不会崩溃。当然,我不希望这样做。请您看看我的代码并找出可以更改的内容。谢谢!!

public DatabaseHelper() throws IOException {
    super(Attendance.getContext(), DB_NAME, null, DB_VERSION);
    /*try {
        createDataBase();
        openDataBase();
    } catch (IOException e) {
        e.printStackTrace();
    }*/
    boolean dbexist = checkDataBase();
    if(dbexist){
        openDataBase();
    }else{
        createDataBase();
    }
}

/**
 * Database maintains global state in application
 * 
 * @return singleton instance
 */
public static DatabaseHelper getInstance() {

    if (mInstance == null) {
        try {
            mInstance = new DatabaseHelper();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return mInstance;
}

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

    boolean dbexist = checkDataBase();
    if (dbexist) {

    }else{
        this.getReadableDatabase();
        try{
            copyDataBase();
        }catch(IOException e){
            throw new Error("Error copying database");
        }
    }
}

/**
 * Check if the database already exist to avoid re-copying the file each
 * time you open the application.
 * 
 * @return true if it exists, false if it doesn't
 */
private boolean checkDataBase() {
    // SQLiteDatabase checkDataBase = null;
    boolean checkDataBase =true;
    try {
        String Path = DB_PATH + DB_NAME;
        File dbFile = new File(Path);
        /*
         * checkDataBase = SQLiteDatabase.openDatabase(Path, null,
         * SQLiteDatabase.OPEN_READONLY);
         */
        checkDataBase = dbFile.exists();
    } catch (SQLiteException e) {
        Log.e("CheckDb", "DB not found");
        // database does't exist yet.
    }
    return checkDataBase;
}

/**
 * Copies your database from local assets-folder to the just created empty
 * database in the system folder, from where it can be accessed and handled.
 * This is done by transfering bytestream.
 * 
 * @throws IOException
 */

private void copyDataBase() throws IOException {

    // Open your local database as the input stream
    InputStream myInput = context.getAssets().open(DB_NAME);

    // Open the empty db as the output stream.
    OutputStream myOutput = new FileOutputStream(DB_PATH + DB_NAME);

    // 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 stream.
    myOutput.close();
    myOutput.flush();
    myInput.close();
    Log.i("Database", "New database has been copied to device!");

}

/**
 * Open the database
 * 
 * @throws SQLException
 */
public boolean openDataBase() throws SQLException {
    String path = DB_PATH + DB_NAME;
    db = SQLiteDatabase.openDatabase(path, null,
            SQLiteDatabase.OPEN_READWRITE);
    Log.i("DB....", "database opened....");
    return db != null;
}

public synchronized void close() {
    if (mInstance != null)
        db.close();
    super.close();
}

Logcat:

02-27 13:30:26.509: D/AndroidRuntime(20480): Shutting down VM
02-27 13:30:26.509: W/dalvikvm(20480): threadid=1: thread exiting with uncaught  exception (group=0x4188eba8)
02-27 13:30:26.509: E/AndroidRuntime(20480): FATAL EXCEPTION: main
02-27 13:30:26.509: E/AndroidRuntime(20480): Process: <package-name>, PID: 20480
02-27 13:30:26.509: E/AndroidRuntime(20480): java.lang.RuntimeException: Unable to start activity ComponentInfo{<package-name>/<package-name>.MainActivity}: java.lang.NullPointerException
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.os.Looper.loop(Looper.java:136)
 02-27 13:30:26.509: E/AndroidRuntime(20480):   at android.app.ActivityThread.main(ActivityThread.java:5017)
 02-27 13:30:26.509: E/AndroidRuntime(20480):   at java.lang.reflect.Method.invokeNative(Native Method)
 02-27 13:30:26.509: E/AndroidRuntime(20480):   at java.lang.reflect.Method.invoke(Method.java:515)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at dalvik.system.NativeStart.main(Native Method)
02-27 13:30:26.509: E/AndroidRuntime(20480): Caused by: java.lang.NullPointerException
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.copyDataBase(DatabaseHelper.java:172)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.createDataBase(DatabaseHelper.java:130)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.<init>(DatabaseHelper.java:94)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.getInstance(DatabaseHelper.java:107)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.model.Portfolio.<init>(Portfolio.java:25)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com .Areva.areva_attendance.MainActivity.onCreate(MainActivity.java:43)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.Activity.performCreate(Activity.java:5231)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
02-27 13:30:26.509: E/AndroidRuntime(20480):    ... 11 more

【问题讨论】:

  • @ShabbirDhangot 我贴了 :)
  • 是第一次打开应用的日志吗? (清除数据或卸载/重新安装后)
  • @Murphy 我做了所有的事情,但它也不是那样工作的。但我弄清楚我的代码在哪里不起作用。你能检查我的 context.getAssets().open();从那条线开始,它正在崩溃。
  • 您是否使用调试模式来跟踪您的代码错误?你遇到了什么错误?空指针异常?你从哪里得到你的上下文?最好将其作为函数参数传递。
  • @Murphy Dude 我怀疑数据库助手类的上下文。我正在尝试使数据库助手类成为扩展应用程序的全局状态应用程序。我再次发布我的 logcat 错误。当数据库试图从资产复制时会发生这种情况。

标签: android mysql database sqlite assets


【解决方案1】:

我想你的 DB_PATH 是硬编码的。

您应该使用Environment.getDataDirectory() 来获取内部存储路径,因为Android 可能会根据设备/操作系统版本将其定位在不同的位置。

【讨论】:

    【解决方案2】:

    说真的!!我不相信这一点。我刚刚在我的应用程序的第一个查询中添加了 db.openDataBase(); 函数,然后它就起作用了。我无法相信这。我现在意识到的是,我应该在查询之前打开数据库。它可能有助于解决此类问题。干杯!! :D

    别忘了在 pause() 和 resume() 上 db.close db.open();

    【讨论】:

    • 我认为使用 context.getAssets().open(); 复制数据库时它会崩溃?
    • @Murphy 没有朋友。它没有崩溃。我的代码没有任何错误。创建并复制到数据库文件夹后,我只是忘记为查询打开数据库。那是我的愚蠢错误。感谢您的帮助:)
    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多