安卓银河的真实设备数据库文件到空点异常



我正在名为mydb的资产中加载一个数据库文件。然后,我使用以下代码将数据库文件加载到模拟器上。这有时有效,但并非总是如此。我重置日食,数据库文件正确加载。我根本无法让它在真实设备上工作。我已经在其他实验文件项目中尝试过这个。我认为有一个设置我没有正确配置,但我不确定。任何帮助将不胜感激。

尝试的方法

  1. 我尝试使用android_meta表,因为建议这样做来解决数据库未加载的问题。

  2. 我也可以使用这种语法进行记录。这甚至可以在现场设备上工作long id = db.insertContact("Wei-Meng Lee", "weimenglee@learn2develop.net"); 这个代码狙击手取自《安卓开发》一书

  3. 我正在对示例中指定的代码进行更改

整个故障日志

06-21 15:17:56.792:E/Android运行时(556):致命异常:main06-21 15:17:56.792: E/AndroidRuntime(556): java.lang.RuntimeException: 无法启动活动 ComponentInfo{alex.android.test.db/alex.android.test.db.AndroidtestdbActivity}: android.database.sqlite.SQLiteException: no 这样的表: 联系人: , 编译时: 选择不同的_id、姓名、电子邮件 来自联系人 其中 _id=206-21 15:17:56.792: E/AndroidRuntime(556): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)06-21 15:17:56.792: E/AndroidRuntime(556): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)06-21 15:17:56.792: E/AndroidRuntime(556): at android.app.ActivityThread.access$600(ActivityThread.java:123)06-21 15:17:56.792: E/AndroidRuntime(556): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)06-21 15:17:56.792: E/AndroidRuntime(556): at android.os.Handler.dispatchMessage(Handler.java:99)06-21 15:17:56.792: E/AndroidRuntime(556): at android.os.Looper.loop(Looper.java:137)06-21 15:17:56.792: E/AndroidRuntime(556): at android.app.ActivityThread.main(ActivityThread.java:4424)06-21 15:17:56.792: E/AndroidRuntime(556): at java.lang.reflect.Method.invokeNative(Native Method)06-21 15:17:56.792: E/AndroidRuntime(556): at java.lang.reflect.Method.invoke(Method.java:511)06-21 15:17:56.792: E/AndroidRuntime(556): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)06-21 15:17:56.792: E/AndroidRuntime(556): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)06-21 15:17:56.792: E/AndroidRuntime(556): at dalvik.system.NativeStart.main(Native Method)06-21 15:17:56.792: E/AndroidRuntime(556): 由: android.database.sqlite.SQLite异常: 没有这样的表: 联系人: , 编译时: 选择不同的_id、姓名、电子邮件 来自联系人,其中 _id=206-21 15:17:56.792: E/Android运行时(556): at android.database.sqlite.SQLiteCompiledSql.native_compile(本机方法)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteCompiledSql.(SQLiteCompiledSql.java:68)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:127)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:94)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:53)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1564)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1449)06-21 15:17:56.792: E/AndroidRuntime(556): at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1405)06-21 15:17:56.792: E/AndroidRuntime(556): at alex.android.test.db.DBAdapter.getContact(DBAdapter.java:163)06-21 15:17:56.792: E/AndroidRuntime(556): at alex.android.test.db.AndroidtestdbActivity.onCreate(AndroidtestdbActivity.java:32)06-21 15:17:56.792: E/AndroidRuntime(556): at android.app.Activity.performCreate(Activity.java:4465)06-21 15:17:56.792: E/AndroidRuntime(556): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)06-21 15:17:56.792: E/AndroidRuntime(556): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)

公共类 DBAdapter {

 private static final String DB_NAME = "MyDB";
private static final int DB_VERSION = 1;
 public static final String KEY_ROWID = "_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_EMAIL = "email";
    private static final String TAG = "DBAdapter";
    private static final String DATABASE_TABLE = "contacts";
private static Context c;
private SQLiteDatabase db;
private SQLiteOpenHelper sqlDBHelp;
/**
 * Constructor for the SQL DB Adapter, copy DB from assets if not exists in /data/data/<package-name>/databases
 * 
 * @param c
 */
public DBAdapter(Context c) {
    super();
    DBAdapter.c = c;
    sqlDBHelp = new SqlDBHelper();
}
/**
 * Open the SQL DB as Writable
 */
public void openDB() {
    try {
        db = sqlDBHelp.getWritableDatabase();
    } catch (SQLiteException ex) {
        Toast.makeText(c, "DB with filename " + DB_NAME + "coudn't be opend!", Toast.LENGTH_SHORT);
    }
}
/**
 * Close the SQL DB
 */
public void closeDB() {
    db.close();
}
/**
 * Helper class for the SQL DB Adapter
 */
static class SqlDBHelper extends SQLiteOpenHelper {
    private static final String DB_PATH = "/data/data/" + c.getPackageName() + "/databases/" + DB_NAME;
    public SqlDBHelper() {
        super(c, DB_NAME, null, DB_VERSION);
        createDB();     
    }
    private void createDB() {
        SharedPreferences prefs = c.getSharedPreferences("sharedPrefs", 0);
        boolean dbExists = prefs.getBoolean("dbExists", false);
        Log.d("PM.ADA.SDA", "DB Exists : " + dbExists);
        if (!dbExists) {
            this.getReadableDatabase();
            copyDB();
            prefs.edit().putBoolean("dbExists", true).commit();
        }
    }

    public void onCreate(SQLiteDatabase db) {
        /*
        try {
            db.execSQL(DATABASE_TABLE); 
        } catch (SQLException e) {
            e.printStackTrace();
        }   
        */
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
         Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS contacts");
            onCreate(db);

    }
    public void copyDB() {
        try {               
            InputStream is = c.getAssets().open(DB_NAME);
            BufferedInputStream bis = new BufferedInputStream(is);
            OutputStream os = new FileOutputStream(DB_PATH);
            BufferedOutputStream bos = new BufferedOutputStream(os);
            byte[] buffer = new byte[64];
            int length;
            while ((length = bis.read(buffer)) > 0) {
                bos.write(buffer, 0, length);
            }
            bos.flush();
            bos.close();
            bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public long insertContact(String name, String email) 
{
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_NAME, name);
    initialValues.put(KEY_EMAIL, email);
    return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular contact---
public boolean deleteContact(long rowId) 
{
    return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---retrieves all the contacts---
public Cursor getAllContacts() 
{
    return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
            KEY_EMAIL}, null, null, null, null, null);
}
//---retrieves a particular contact---
public Cursor getContact(long rowId) throws SQLException 
{
    Cursor mCursor =
            db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
            KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null,
            null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}
//---updates a contact---
public boolean updateContact(long rowId, String name, String email) 
{
    ContentValues args = new ContentValues();
    args.put(KEY_NAME, name);
    args.put(KEY_EMAIL, email);
    return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}

}

其他活动 文本视图名称;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    DBAdapter db = new DBAdapter(this); 
    name = (TextView)findViewById(R.id.name);

    //---get a contact---
    db.openDB();
    Cursor c = db.getContact(2);
    if (c.moveToFirst())  
    {
        DisplayContact(c);
    name.setText(String.valueOf(c.getString(1)));
    }
    else
        name.setText("not found");
        Toast.makeText(this, "No contact found", Toast.LENGTH_LONG).show();
    db.closeDB();
}
public void DisplayContact(Cursor c)
{
    Toast.makeText(this, 
            "id: " + c.getString(0) + "n" +
            "Name: " + c.getString(1) + "n" +
            "Email:  " + c.getString(2),
            Toast.LENGTH_LONG).show();  

}  

}

我看到与我的做法有一些不同...... 您缺少outputStream.flush(),我在开始复制过程之前和之后this.close();打电话给this.getReadableDatabase();

供您参考,这是我的操作方法,它工作正常:

private static class DatabaseHelper extends SQLiteOpenHelper {
    DatabaseHelper(Context context, String dbname, int dbversion) {
        super(context, dbname, null, dbversion);
        if (checkDataBase(dbname)) {
            openDataBase(dbname);
        } else {
            try {
                this.getReadableDatabase();
                copyDataBase(dbname);
                this.close();
                openDataBase(dbname);
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
            Toast.makeText(context,
                    "Initial " + dbname + " database has been created",
                    Toast.LENGTH_LONG).show();
        }
    }

public DBAdapter(Context ctx) {
    DBAdapter.mCtx = ctx;
}
private static boolean checkDataBase(String dbname) {
    SQLiteDatabase checkDB = null;
    boolean exist = false;
    try {
        String db = MAIN_DB_PATH + dbname;
        checkDB = SQLiteDatabase.openDatabase(db, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {
        Log.v("db log", "database does't exist");
    }
    if (checkDB != null) {
        exist = true;
        checkDB.close();
    }
    return exist;
}
private static void copyDataBase(String dbname) throws IOException {
    InputStream myInput = mCtx.getAssets().open(dbname);
    String outFileName = MAIN_DB_PATH + dbname;
    OutputStream myOutput = new FileOutputStream(outFileName);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }
    myOutput.flush();
    myOutput.close();
    myInput.close();
}