Android的SQLite的多线程访问 [英] Android SQlite multithread access

查看:182
本文介绍了Android的SQLite的多线程访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用SQLiteOpenHelper写和Android上的SQLite数据库中读取。当用户点击UI我使用AsyncTask的SQLite数据库读取,但在具体萨莫那一刻我更新和使用其他的AsyncTask写入数据库的背景。

每x次,我得到的数据库锁定异常。我该如何解决这个问题?可以SQLite的某种方式访问​​从多个线程在同一时间?

我用它这样的:我有从SQLiteOpenHelper扩展数据库类。我实现的onCreate和onUpgrade方法,每次我读从数据库或写入数据库我用SQLiteDatabase这样的:

  SQLiteDatabase数据库= NULL;
尝试 {

    数据库=新的数据库(上下文).getWritableDatabase();

    ....
    写,从数据库中读取...
    ....

}赶上(例外五){
    e.printStackTrace();
} 最后 {
    如果(数据库!= NULL){
        database.close();
    }
}
 

目前我还靠近SQLiteStatements和光标如果我使用他们的结束。我应该用@Justin答案,有数据库类的单一的应用程序?

这是我的错误:

  E / SqliteDatabaseCpp(17377):sqlite3_open_v2(/数据/数据​​/ com.skulptur /数据库/ LGM.s3db,和放大器;手柄,6,NULL)失败
E / SQLiteDatabase(17377):无法打开数据库。关闭它。
E / SQLiteDatabase(17377):android.database.sqlite.SQLiteDatabaseLockedException:数据库已锁定
E / SQLiteDatabase(17377):在android.database.sqlite.SQLiteDatabase.dbopen(本机方法)
E / SQLiteDatabase(17377):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
E / SQLiteDatabase(17377):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
E / SQLiteDatabase(17377):在android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
E / SQLiteDatabase(17377):在android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:750)
E / SQLiteDatabase(17377):在android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
E / SQLiteDatabase(17377):在android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
E / SQLiteDatabase(17377):在android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:223)
 

解决方案

这是我做什么,以避免锁定问题。我让我的应用程序处理我的分贝帮手的一个实例,总是指它在获得一个句柄我的数据库。

 公共类MyApp的扩展应用{
    //我SQLiteOpenHelper实例
    公共静态DbHelper openHelper;

    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        如果(openHelper == NULL){
            openHelper =新DbHelper(本);
        }
    }

    公共同步静态SQLiteDatabase getDB(){
        返回openHelper.getWritableDatabase();
    }
}
 

一旦你做到这一点,任何时候你想要做一个数据库查询,得到这样MyApp.getDB分贝手柄(),你将永远不会有一个锁定问题。一定要永不落幕的DB虽然。这个方式保持在任何时候都在你的应用程序的单一连接。 SQLite的,就是要同步在Android上,所以如果你有长时间运行的数据库的进程,像1000刀片在单个事务中你要code这样的:

  db.beginTransaction();
尝试 {
    对于(DBRow行:insertList){
        //您插入code
        的insertRow(行);
        db.yieldIfContendedSafely();
    }
    db.setTransactionSuccessful();
} 最后 {
    db.endTransaction();
}
 

这将允许其它查询插自己,使你不会看到在后台更新你的应用程序停顿下来。

I am using SQLiteOpenHelper to write and read from SQlite database on Android. When user clicks on UI I read from SQLite database using AsyncTask but at the exact samo moment I am updating and writing to the database in the background using other AsyncTask.

Every x times I get database locked exception. How can I fix this? Can SQlite be accessed somehow from multiple thread at the same time?

I am using it like that: I have a Database class which extends from SQLiteOpenHelper. I implemented onCreate and onUpgrade methods and everytime I am reading from database or writing to database I use SQLiteDatabase like that:

SQLiteDatabase database = null;
try {

    database = new Database(context).getWritableDatabase();

    ....
    writing and reading from database...
    ....

} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (database != null) {
        database.close();
    }
}

At the end I also close SQLiteStatements and Cursors if I use them. Should I use @Justin answer and have a singleton of database class in Application?

This is the error I get:

E/SqliteDatabaseCpp(17377): sqlite3_open_v2("/data/data/com.skulptur/databases/LGM.s3db", &handle, 6, NULL) failed
E/SQLiteDatabase(17377): Failed to open the database. closing it.
E/SQLiteDatabase(17377):     android.database.sqlite.SQLiteDatabaseLockedException: database is locked
E/SQLiteDatabase(17377):    at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
E/SQLiteDatabase(17377):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983)
E/SQLiteDatabase(17377):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956)
E/SQLiteDatabase(17377):    at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021)
E/SQLiteDatabase(17377):    at   android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:750)
E/SQLiteDatabase(17377):    at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
E/SQLiteDatabase(17377):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
E/SQLiteDatabase(17377):    at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:223)

解决方案

This is what I do to avoid locking issues.. I let my application handle a single instance of my db helper and always refer to it to get a handle on my DB.

public class MyApp extends Application {
    // My instance of SQLiteOpenHelper
    public static DbHelper openHelper;

    @Override
    public void onCreate() {
        super.onCreate();
        if (openHelper == null) {
            openHelper = new DbHelper(this);
        }
    }

    public synchronized static SQLiteDatabase getDB() {
        return openHelper.getWritableDatabase();
    }
}

Once you do this, anytime you want to do a db query, get the db handle like MyApp.getDB() and you will never have a locking issue. Be sure to NEVER close the DB though. This pattern maintains a single connection at all times in your app. SQLite is meant to be synchronous on Android so if you have long running DB processes, like a 1000 inserts in a single transaction you'll want to code it like this:

db.beginTransaction();
try {
    for (DBRow row : insertList) {
        // your insert code
        insertRow(row);
        db.yieldIfContendedSafely();
    }
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

This will allow other queries to interject themselves so that you won't see your app grind to a halt during background updates.

这篇关于Android的SQLite的多线程访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆