使用SQLite数据库运行Android应用程序时出现数据库错误

时间:2011-11-04 02:24:12

标签: android sqlite android-emulator

特定错误:尝试访问数据/数据/包/数据库时,带有SQLite数据库的Android应用程序失败

注意:我知道Stackoverflow上发布了很多文章,以及一些推荐的网站,关于如何将sqlite文件从Assets文件夹复制到data / data / package / databases文件夹中。但是,我的实现仅适用于模拟器而非真实设备。我想我错过了一块拼图。

我的问题 任何人都可以识别我的代码中的失败点吗?我真的认为这是一双新鲜的眼睛会很快发现错误的事情之一。提前感谢您提供的任何见解......

错误日志(BOLD项目是失败点): 11-02 20:22:17.045:INFO / Process(15318):发送信号。 PID:15318 SIG:9 11-02 20:22:17.055:INFO / ActivityManager(2697):进程com.game.myapp(pid 15318)已经死亡。 11-02 20:22:17.055:INFO / WindowManager(2697):胜利死亡:窗口{40922a70 com.game.myapp / com.game.myapp.MainActivity paused = true}

我的代码

public class DatabaseHelper extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "ttg.db";
public static String DATABASE_PATH = "/data/data/com.game.myapp/databases/";

private SQLiteDatabase ttgDatabase;
private Context myContext = null;

DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.myContext = context;
}



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

        this.getReadableDatabase();

            try {
                copyDataBase();

                    } catch (IOException e) {
                  throw new Error("Error copying database");
                }   
            }
          }


                 private boolean checkDataBase(){
                        SQLiteDatabase checkDB = null;

                        try{
                    String myPath = DATABASE_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{
                    File fileTest = myContext.getFileStreamPath(DATABASE_NAME);
                            boolean exists = fileTest.exists();
                    if (!exists) {

            OutputStream databaseOutputStream = new FileOutputStream(DATABASE_PATH + DATABASE_NAME);
            InputStream databaseInputStream;

             databaseInputStream = myContext.getAssets().open(DATABASE_NAME);
                    byte[] buffer = new byte[1024];
             int length;
                while ((length = databaseInputStream.read(buffer)) > 0) {
               databaseOutputStream.write(buffer);
             }
                // Close the streams
               databaseInputStream.close();
               databaseOutputStream.flush();
                   databaseOutputStream.close();
                 }
               }

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

                      @Override
                public synchronized void close() {
                        if(ttgDatabase != null)
                            ttgDatabase.close();
                super.close();
        }


@Override
public void onCreate(SQLiteDatabase db) {

}


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

}

1 个答案:

答案 0 :(得分:0)

下面。您可能有损坏的数据库文件(实际上,您不需要1024个中的1个)

while ((length = databaseInputStream.read(buffer)) > 0) {
    databaseOutputStream.write(buffer);
}

需要指定写入时读取的缓冲区长度。你会得到的是每次写入的整个1024字节。

我讨厌编写“InputStream / OutputStream”复制代码,我看到它到处都是。如果你想使用它,我创建了一个精简版的apache commons库。你从来没有使用过很多东西,但其中有一些很棒的实用代码:

http://www.touchlab.co/blog/android-mini-commons/

否则,请使用此方法代替您现在使用的方法:

http://download.oracle.com/javase/1.4.2/docs/api/java/io/OutputStream.html#write(byte[], int, int)