我应该如何小心是线程安全创建方法/活动,与SQLite数据库进行交互时? [英] How careful should I be with thread-safety when creating methods/activities which interact with SQLite database?

查看:182
本文介绍了我应该如何小心是线程安全创建方法/活动,与SQLite数据库进行交互时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建一个应用程序,它允许许多不同的活动从一个 TabActivity (可达开始〜 25)。大部分的活动都需要从SQLite数据库的数据,所以当的onCreate 运行,一个的AsyncTask 创建一个SQLiteOpenHelper对象(这将打开一个可读/可写数据库),运行查询,数据被检索,并且一切然后关闭。

我只是测试插科打诨,看看我是否能打破一些东西,所以我说每一个活动 TabActivity的 TabHost 。然后我开始糖化每个选项卡尽可能快地。

我注意到,很快我开始看到在LogCat中:致:android.database.sqlite.SQLiteException:数据库被锁定:BEGIN EXCLUSIVE; 和应用程序接着就不行了。

通常只会有大约4-6片(我可以限制反正用户)为 TabHost 。我还没有能够用少量的标签,以混搭的破坏任何东西,但我仍然担心,也许我在一个贫穷的方式访问数据库。

我怎样才能prevent我SQLiteDatabase对象造成锁?

如果我创建一个的ContentProvider 的意志,消除了数据库锁定的可能性?

你有什么建议改变我能对访问数据的 SQLiteDatabase

我最终采取使用应用程序类和存储1 SQLiteOpenHelper 并尽我所能保持的方法它同步。这似乎是伟大的工作 - 我把我所有的25项活动中的 TabHost 和捣碎的离开对他们没有错误

我打电话((SQLiteDbApplication)getApplication())setDbHelper(新DBHelper(这一点,Constants.DB_NAME,空,Constants.DB_VERSION_ code)); 方法(如下图所示),在每一个的onCreate()在我的活动

任何进一步的建议,以这种方式,或者我做了使用该应用程序的更改类?

 进口android.app.Application;
进口android.database.sqlite.SQLiteDatabase;

公共类SQLiteDbApplication扩展应用{
    私人DBHelper dbHelper;
    私人SQLiteDatabase分贝;
    公共同步DBHelper getDbHelper(){
        DB = dbHelper.getDatabase(); //返回已经打开的数据库对象
        而(db.isDbLockedByCurrentThread()|| db.isDbLockedByOtherThreads());
        返回dbHelper;
    }
    市民同步无效closeDb(){
        如果(NULL!= dbHelper)
            dbHelper.close();
        如果(NULL!= DB)
            db.close();
    }

    @覆盖
    保护无效的finalize()抛出的Throwable
        如果(NULL!= dbHelper)
            dbHelper.close();
        如果(NULL!= DB)
            db.close();
        super.finalize();
    }
    市民同步无效setDbHelper(DBHelper dbHelper){
        如果(空== this.dbHelper){
            this.dbHelper = dbHelper;
            this.dbHelper.setDb(this.dbHelper.getWritableDatabase()); //创建并经由getWritableDatabase设置数据库对象()
        }
    }
}
 

解决方案

如果你是担心所有的数据库连接,尽量限制自己一个SqliteOpenHelper,一定要环绕它同步层。

您可以延长应用类,然后调用的 getApplication 投下你进入你的应用程序中的对象。现在,您可以存储在这个应用类SqliteOpenHelper并建立自己的线程安全访问方法数据库连接。

如果您在您的所有的onCreate方法使用的AsyncTask和您遇到的问题有很多标签,也可能发生与较慢的设备,更快的用户或生长大了使用时的数据库中的这些问题。

于使用情况根据你的应用程序,你可以去保存方式通过所有的努力和线程和锁定的疼痛,或者你可以有多个选项卡,从来没有产生的错误,并确保发布的应用程序捕捉数据库异常,并给自己发送通知(例如,通过谷歌分析)来测试,如果确实发生在应用程序的实际生活使用的线程问题。

I am creating an app which allows for many different Activities to be started from a TabActivity(up to ~25). Most of the activities require data from the sqlite database, so when onCreate is run, an AsyncTask creates an SQLiteOpenHelper object(which will open a readable/writable database), runs a query, data is retrieved, and everything is then closed.

i was just testing messing around to see if i could break something, so i added every Activityto the TabActivity's TabHost. I then started mashing each tab as quickly as possible.

i noticed that very quickly i began to see in the LogCat: Caused by: android.database.sqlite.SQLiteException: database is locked: BEGIN EXCLUSIVE; and the app proceeded to die.

Typically there will only be about 4-6 tabs(i can just limit the user anyway) for the TabHost. I haven't been able to break anything with a small amount of tabs to mash, but i am still worried that maybe i am accessing the database in a poor way.

How can i prevent my SQLiteDatabase objects to cause a lock?

If i create a ContentProvider will that eliminate the possibility of database locking?

Do you have any suggestions for changes I could make for accessing data from an SQLiteDatabase?

I ended up taking the approach of using the Application class and storing 1 SQLiteOpenHelper and trying my best to keep it synchronized. This seems to be working great - i put all my 25 activities in the TabHost and mashed away on them with no errors.

I am calling ((SQLiteDbApplication)getApplication()).setDbHelper(new DBHelper(this, Constants.DB_NAME, null, Constants.DB_VERSION_CODE)); method(shown below) in every onCreate() in my activities

Any further suggestions to this approach or to the changes i made using this Application class?

import android.app.Application;
import android.database.sqlite.SQLiteDatabase;

public class SQLiteDbApplication extends Application {
    private DBHelper dbHelper;
    private SQLiteDatabase db;
    public synchronized DBHelper getDbHelper() {
        db = dbHelper.getDatabase();//returns the already opened database object
        while(db.isDbLockedByCurrentThread() || db.isDbLockedByOtherThreads());
        return dbHelper;
    }
    public synchronized void closeDb() {
        if(null != dbHelper)
            dbHelper.close();
        if(null != db)
            db.close();
    }

    @Override
    protected void finalize() throws Throwable {
        if(null != dbHelper)
            dbHelper.close();
        if(null != db)
            db.close();
        super.finalize();
    }
    public synchronized void setDbHelper(DBHelper dbHelper) {
        if(null == this.dbHelper) {
            this.dbHelper = dbHelper;
            this.dbHelper.setDb(this.dbHelper.getWritableDatabase());//creates and sets the database object via getWritableDatabase()
        }
    }
}

解决方案

If you are to worried about all the database connections try to limit yourself to one SqliteOpenHelper and be sure to wrap a synchronization layer around it.

You can extend the application class and then call getApplication and cast the object you get into your application. Now you can store a SqliteOpenHelper in this application class and build your own thread safe access method to the database connection.

If you are using AsyncTask in all of your onCreate methods and you are experiencing problems with a lot of tabs these problems can also occur with a slower device, a faster user or a database that is grown big over the time of usage.

Depending on the use case of you app you can go the save way and go through all the effort and pain of threading and locking, or you can just publish the app with a number of tabs that never produced the error and be sure to catch the database exception and send yourself a notification (for example through google analytics) to test if the threading problem does occur in real life usage of the app.

这篇关于我应该如何小心是线程安全创建方法/活动,与SQLite数据库进行交互时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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