我正在学习机器人,而不是专家。我想在处理我的sqllite数据库时遇到了一些逻辑问题。让我解释一下我在做什么以及我得到了什么。
我有一个引用的应用程序。我也在线提供本地数据库。我在数据库中包含了数据库文件,并在用户从启动画面打开应用程序时首次从中复制数据库。之后,我检查存储在用户设备中的最后作者和本地数据库的最后一个引号,并与在线数据库进行比较。如果在线有新数据,那么我正在下载并将其存储在初始屏幕中。
现在我的启动画面代码如下所示
DAO database=DAO.getInstance(this);
int lastAuthor =database.getLastAuthor();
String updatesUrl = constant.MainUrl + String.valueOf(lastAuthor)+ "/" + String.valueOf(lastQuote);
我的DAO课程看起来像这样
public class DAO {
private SQLiteDatabase database;
private DBHandler dbHandler;
private static final String TABLE_QUOTES = "quotes";
private static final String TABLE_AUTHORS = "authors";
private static final String TABLE_SETTINGS = "settings";
private static final String QU_ID = "_quid";
private static final String QU_TEXT = "qu_text";
private static final String QU_AUTHOR = "qu_author";
private static final String QU_FAVORITE = "qu_favorite";
private static final String QU_TIME = "qu_time";
private static final String AU_NAME = "au_name";
private static final String AU_PICTURE = "au_picture";
private static final String AU_PICTURE_SDCARD = "au_picture_sdcard";
private static final String AU_WEB_ID = "au_web_id";
private static DAO dBObject;
private final Object lockObj=new Object();
public static DAO getInstance(Context context){
if(dBObject==null)dBObject=new DAO(context);
return dBObject;
}
private DAO(Context context) {
synchronized (lockObj) {
dbHandler = new DBHandler(context);
try {
dbHandler.createDataBase();
} catch (IOException e) {
e.printStackTrace();
}
dbHandler.openDataBase();
open();
}
}
public int getLastAuthor() {
String query = "SELECT " + AU_WEB_ID + " FROM " + TABLE_AUTHORS
+ " ORDER BY " + AU_WEB_ID + " DESC LIMIT 1";
Cursor cursor = database.rawQuery(query, null);
cursor.moveToFirst();
int tmp = cursor.getInt(cursor.getColumnIndex(AU_WEB_ID));
cursor.close();
return tmp;
}
// ==============================================================================
public int getLastQuote() {
String query = "SELECT " + QU_ID + " FROM " + TABLE_QUOTES
+ " ORDER BY " + QU_ID + " DESC LIMIT 1";
Cursor cursor = database.rawQuery(query, null);
cursor.moveToFirst();
int tmp = cursor.getInt(cursor.getColumnIndex(QU_ID));
cursor.close();
return tmp;
}
// ==============================================================================
public void addAuthor(String au_name, String au_picture, int au_web_id) {
open();
ContentValues v = new ContentValues();
v.put(AU_NAME, au_name);
v.put(AU_PICTURE, au_picture);
v.put(AU_PICTURE_SDCARD, 1);
v.put(AU_WEB_ID, au_web_id);
database.insert(TABLE_AUTHORS, null, v);
}
// ==============================================================================
public void addQuote(String qu_text, int qu_author, int _quid, String qu_time) {
open();
ContentValues v = new ContentValues();
v.put(QU_TEXT, qu_text);
v.put(QU_AUTHOR, qu_author);
v.put(QU_FAVORITE, "0");
v.put(QU_ID, _quid);
v.put(QU_TIME, qu_time);
database.insert(TABLE_QUOTES, null, v);
}
// ==============================================================================
//method changed
private void open() throws SQLException {
if(database!=null&&database.isOpen())return; //changed line
database = dbHandler.getWritableDatabase();
}
// ==============================================================================
public void closeDAO(){
synchronized (lockObj){
if(dbHandler!=null)dbHandler.close();
dbHandler=null;
database=null;
}
}
public static void dispose(){
if(dBObject!=null){
dBObject.closeDAO();
}
dBObject=null;
}
}
我的数据库处理程序类看起来像这样
public class DBHandler extends SQLiteOpenHelper {
private static String DB_PATH;
private static String DB_NAME = "xxx";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DBHandler(Context context) {
super(context, DB_NAME, null, constant.DATABASE_VERSION);
this.myContext = context;
DB_PATH = context.getDatabasePath(DB_NAME).toString();
}
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 checkDB = null;
try {
String myPath = DB_PATH;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
private void copyDataBase() throws IOException {
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH;
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();
}
// ==============================================================================
public void openDataBase() throws SQLException {
// Open the database
String myPath = DB_PATH;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
// ==============================================================================
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
// ==============================================================================
@Override
public void onCreate(SQLiteDatabase db) {
}
// ==============================================================================
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
我在logcat中遇到这样的错误
Failed to open database '/data/user/0/com.newdeveloper.test/databases/xxx'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:835)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:820)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:723)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:692)
at com.newdeveloper.test.utility.DBHandler.checkDataBase(DBHandler.java:69)
at com.newdeveloper.test.utility.DBHandler.createDataBase(DBHandler.java:32)
at com.newdeveloper.test.utility.DAO.<init>(DAO.java:41)
at com.newdeveloper.test.utility.DAO.getInstance(DAO.java:31)
at com.newdeveloper.test.activities.SplashScreensActivity.checkForUpdate(SplashScreensActivity.java:111)
at com.newdeveloper.test.activities.SplashScreensActivity.access$000(SplashScreensActivity.java:41)
at com.newdeveloper.test.activities.SplashScreensActivity$1.onAnimationEnd(SplashScreensActivity.java:98)
at android.view.animation.AnimationSet.getTransformation(AnimationSet.java:400)
然而,应用程序不会崩溃并且正常工作 需要。但是这个错误让我感到困惑,我需要改变它 解决这个错误。我想从最近两天解决但不是 找到任何有效的解决方案。如果有高级开发人员,请告诉我 可以帮助我从这里出来。感谢
答案 0 :(得分:0)
如果您尚未在apk中使用捆绑数据库,则实际上并未在代码中创建数据库。
@Override
public void onCreate(SQLiteDatabase db) {
//you must create the database here
}
// ==============================================================================
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//Handle the database update here
}
你需要做这样的事情。
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(CREATE_STRING);
} catch (SQLException e) {
e.printStackTrace();
}
Log.e(TAG, "Table Created");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_STRING);
onCreate(db);
Log.d(TAG, "Table upgraded to Version :" + newVersion);
}
我还建议开始使用ROOM Android Architecture Component,它为模式使用的Sqlite提供了更好的抽象级别。