最近在使用多线程下载多个文件,在下载过程当中有下载得快的也有下载的慢的。
最后却报错出了这个错误:
android.database.sqlite.SQLiteException: database is locked
当然不是每次都出,偶尔会出。
出于我想看看到底是为什么,在网上搜索了找到了原因:
可以在出处去看也知道是什么原因了。
http://blog.sina.com.cn/s/blog_74c22b2101010cwo.html
意思就是不要使用两个数据库连接
在多线程下载里面有自带的一个数据库管理类,使用的是和本应用同一个数据库,但是使用的DBHelper却不是同一个。
这是多线程下载Demo里的:
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.wwj.download.db.DBOpenHelper;
/**
* 业务bean
*
*/
public class FileService {
private DBOpenHelper openHelper;
public FileService(Context context) {
openHelper = new DBOpenHelper(context);
}
/**
* 获取每条线程已经下载的文件长度
*
* @param path
* @return
*/
public Map<Integer, Integer> getData(String path) {
SQLiteDatabase db = openHelper.getReadableDatabase();
Cursor cursor = db
.rawQuery(
"select threadid, downlength from filedownlog where downpath=?",
new String[] { path });
Map<Integer, Integer> data = new HashMap<Integer, Integer>();
while (cursor.moveToNext()) {
data.put(cursor.getInt(0), cursor.getInt(1));
}
cursor.close();
db.close();
return data;
}
/**
* 保存每条线程已经下载的文件长度
*
* @param path
* @param map
*/
public void save(String path, Map<Integer, Integer> map) {// int threadid,
// int position
SQLiteDatabase db = openHelper.getWritableDatabase();
db.beginTransaction();
try {
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
db.execSQL(
"insert into filedownlog(downpath, threadid, downlength) values(?,?,?)",
new Object[] { path, entry.getKey(), entry.getValue() });
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
db.close();
}
/**
* 实时更新每条线程已经下载的文件长度
*
* @param path
* @param map
*/
public void update(String path, int threadId, int pos) {
SQLiteDatabase db = openHelper.getWritableDatabase();
db.execSQL(
"update filedownlog set downlength=? where downpath=? and threadid=?",
new Object[] { pos, path, threadId });
db.close();
}
/**
* 当文件下载完成后,删除对应的下载记录
*
* @param path
*/
public void delete(String path) {
SQLiteDatabase db = openHelper.getWritableDatabase();
db.execSQL("delete from filedownlog where downpath=?",
new Object[] { path });
db.close();
}
}
能看到有自己开一个DbHelper。
最后解决办法是在自己写的数据库管理类把这边的方法给移植过去,在这边调用就可以了,保证使用的是同一个数据库链接。
这里附上一个多线程下载的demo(也是搜索而来,直接传入给个链接就可以用,不过需要自己在上面那个类里去抽一下数据库代码以免报本文章错误):
http://pan.baidu.com/s/1pJZQCd1
mnxn