Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android SQlite多线程访问_Android_Database_Multithreading_Android Sqlite - Fatal编程技术网

Android SQlite多线程访问

Android SQlite多线程访问,android,database,multithreading,android-sqlite,Android,Database,Multithreading,Android Sqlite,我正在使用SQLiteOpenHelper在Android上从SQlite数据库进行写和读操作。当用户单击UI时,我使用AsyncTask从SQLite数据库中读取数据,但就在samo时刻,我正在使用其他AsyncTask在后台更新和写入数据库 每x次我得到数据库锁定异常。我怎样才能解决这个问题?可以同时从多个线程访问SQlite吗 我是这样使用它的:我有一个从SQLiteOpenHelper扩展而来的数据库类。我实现了onCreate和onUpgrade方法,每次从数据库中读取或写入数据库时,

我正在使用SQLiteOpenHelper在Android上从SQlite数据库进行写和读操作。当用户单击UI时,我使用AsyncTask从SQLite数据库中读取数据,但就在samo时刻,我正在使用其他AsyncTask在后台更新和写入数据库

每x次我得到数据库锁定异常。我怎样才能解决这个问题?可以同时从多个线程访问SQlite吗

我是这样使用它的:我有一个从SQLiteOpenHelper扩展而来的数据库类。我实现了onCreate和onUpgrade方法,每次从数据库中读取或写入数据库时,我都会像这样使用SQLiteDatabase:

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();
    }
}
最后,如果我使用SQLite语句和游标,我也会关闭它们。我是否应该使用@Justin answer并在应用程序中使用数据库类的单例

这是我得到的错误:

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)

没有什么东西可以尝试。 首先尝试将相同的
SQLiteOpenHelper
实例传递给您的每个任务。 第二种方法是在助手内的SQLiteDatabase上使用beginTransaction和endTransaction。
第三种方法是将
synchronized
添加到任务中使用的每个助手方法。

我认为您使用的数据库连接不正确。它可能是由未关闭的游标或smth等引起的。Sqlite数据库实现是线程安全的,可以从不同的线程同时访问。 请提供有关您的问题的更多详细信息(异常堆栈跟踪、导致异常的代码示例等),以便我们能够帮助您。

在数据库顶部实现一个线程,它将处理线程。
您可以参考本教程:

这是我为避免锁定问题所做的。。我让我的应用程序处理我的db助手的一个实例,并总是引用它来获得我的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();
    }
}
一旦你这样做了,任何时候你想做一个db查询,像MyApp.getDB()一样获得db句柄,你就永远不会有锁定问题。但千万不要关闭数据库。此模式在应用程序中始终保持单个连接。SQLite在Android上是同步的,因此,如果您有长时间运行的DB进程,比如在一个事务中插入1000个,您将希望这样编码:

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

这将允许其他查询插入它们自己,这样你就不会看到你的应用程序在后台更新时陷入停顿。

我认为你在sqllite上使用android库所能做的一切都是同步的。你能不能试着捕捉异常并在获得锁定状态后再试一次?你能编辑你的帖子并给出异常的前几行和任何原因陈述?我怀疑这与你正在做的事情无关,而更多的是关于重新使用一个封闭的数据库或其他东西。你可以使你的
SQLiteOpenHelper
成为一个比重写
应用程序
类更好的单例。是的,我在写了这篇文章后意识到:-\。。我不想更改我的回答我恐怕你错误地认为永远不会有锁定问题:你唯一正在同步的是对
getWritableDatabase
方法的访问,意思是:只有这个方法永远不会被同时调用,它返回的
SQLiteDatabase
对象会发生什么情况,未同步。您的方式很好,但我更喜欢ContentProvider,它将应用程序和数据库分离。你也可以考虑Ormiite或另一个类似ORM的LIB,其中有很多,很好的例子是CROM,我以前做过什么,你如何从不同的线程访问SQLite DB,除了主UI?我读了几遍,说这是办不到的。