这是我的问题。我的应用程序启动多个线程,每个线程用于要更新的特定对象。对象的更新通过对单个数据库的查询进行。有一个数据库和一个 OpenHelper。我的应用程序的行为表明对数据库的调用不是同时进行的,正如我所希望的那样。如何同时从不同线程访问同一个数据库?如果每个对象的数据位于不同的表中,将数据库拆分为多个数据库(每个对象一个)会更有效吗?
public class SomethingToBeUpdated implements Runnable {
private SQLiteDatabase db;
@Override
public void run() {
db.rawQuery( ... bla bla
}
}
public class MainActivity extends Activity {
private SomethingToBeUpdated[] list = bla bla...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
for( SomethingToBeUpdated x : list ) {
new Thread(x).start();
}
}
}
最佳答案
为了在不同的线程中访问数据库,您需要有一个数据库管理器,它保留数据库类的对象并将其传递给任何需要它的线程。在android中,你不能在具有不同对象的多个线程中同时访问数据库。它可能只会阻塞你的用户界面(我几天前遇到的问题)。
因此,为了解决这个问题,您可以使用我使用的数据库管理器,其定义如下:
public class DatabaseManager {
private AtomicInteger mOpenCounter = new AtomicInteger();
private static DatabaseManager instance;
private static SQLiteOpenHelper mDatabaseHelper;
private SQLiteDatabase mDatabase;
public static synchronized void initializeInstance(SQLiteOpenHelper helper) {
if (instance == null) {
instance = new DatabaseManager();
mDatabaseHelper = helper;
}
}
public static synchronized DatabaseManager getInstance() {
if (instance == null) {
throw new IllegalStateException(DatabaseManager.class.getSimpleName() +
" is not initialized, call initializeInstance(..) method first.");
}
return instance;
}
public synchronized SQLiteDatabase openDatabase() {
if(mOpenCounter.incrementAndGet() == 1) {
mDatabase = mDatabaseHelper.getWritableDatabase();
}
return mDatabase;
}
public synchronized void closeDatabase() {
if(mOpenCounter.decrementAndGet() == 0) {
mDatabase.close();
}
}
}
然后你像这样初始化一次:
DatabaseManager.initializeInstance(new ChatSQL(c));
然后您可以使用以下语法在任何地方获取数据库对象:
SQLiteDatabase db = DatabaseManager.getInstance().openDatabase(); //in your methods which are querying the database
使用此方法,您的数据库现在是线程安全的。希望这会有所帮助。
If the data for each object are in different tables is more efficient to split the database in several databases, one for each object?
不,它效率不高。定义、访问、创建对象和查询不同的数据库有很多开销。如果你想加入表怎么办?你就是不能。
关于android - 从不同线程同时访问 SQLite 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28489238/