Android SQLite查询、插入、更新、删除操作,是否总是需要在后台线程上运行?

19

我目前使用加载器(Loaders)从我的ContentProvider获取数据(以启用游标的自动更新)。这种方法适用于查询数据库,但似乎不适合其他任何数据库操作(如插入、更新、删除)。

我的问题是:

  1. 所有SQLite操作是否都需要在后台线程上执行,或者在UI线程上执行简单的操作(如插入、更新或删除单个行)是安全的?
  2. 有什么设计模式可以确保所有查询都通过后台线程进行?我想实现AsyncTask,我应该创建一个类似于SuperTask的东西,它扩展了AsyncTask并执行每个SQLite操作吗?(奖励:您能提供一个最简示例吗?)

我们应该为批量操作使用后台线程......在UI线程上可以执行单行插入、更新或删除。 - dd619
2个回答

6
我在UI线程上进行了SQLite操作。我想问题实际上变成了你的查询是否需要很长时间。我从未遇到过由于在SQLite数据库上执行SQL调用而导致应用程序崩溃的情况。
话虽如此,如果您计划编写复杂查询,则需要将其作为AsyncTask或Thread运行,并使用回调来更新必要的UI。
这是一篇关于Android SQLite的优秀教程(它还解决了一些您提到的复杂SQL时间问题):http://www.vogella.com/tutorials/AndroidSQLite/article.html

谢谢您的回复。我猜这可能会很快变得混乱,因为您需要为每种类型的查询定义一个新的AsyncTask,或者您需要将switch语句添加到主AsyncTask中以处理所有内容,这通常是在AsyncTask中进行后台线程处理的方式吗? - AutoM8R
你不需要为每个查询创建一个特定的任务,但是你可以创建一个特定的任务来处理所有的数据库请求。因此,它在你的活动后台运行,执行一系列查询并在实际的AsyncTask上安排查询和回调。在后台,你可以使用BlockingQueue持续地连接到你的数据库,以提供一个命令来调用你的DB。在你的UI线程上,你只需要将一个命令添加到队列中即可。 - user695992

5
  1. 所有SQLite操作并非必须在后台进行,但应该这样做。即使是简单的行更新也会影响UI线程,从而影响应用程序的响应性。

  2. Android包括AsyncQueryHandler抽象类:

    一个帮助处理异步ContentResolver查询的辅助类。

以下是在Android中使用AsyncQueryHandler异步访问内容提供程序中的两个示例实现。一个成员类:

class MyQueryHandler extends AsyncQueryHandler {

    public MyQueryHandler(ContentResolver cr) {
        super(cr);
    }

    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
        // query() completed
    }

    @Override
    protected void onInsertComplete(int token, Object cookie, Uri uri) {
        // insert() completed
    }

    @Override
    protected void onUpdateComplete(int token, Object cookie, int result) {
        // update() completed
    }

    @Override
    protected void onDeleteComplete(int token, Object cookie, int result) {
        // delete() completed
    }
}

一个匿名类:
AsyncQueryHandler queryHandler = new AsyncQueryHandler(getContentResolver()) {
    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {

        if (cursor == null) {
            // Some providers return null if an error occurs whereas others throw an exception
        }
        else if (cursor.getCount() < 1) {
            // No matches found
        }
        else {

            while (cursor.moveToNext()) {
                // Use cursor
            }

        }
    }
};

更多细节:

  1. 实现AsyncQueryHandler

  2. http://www.trustydroid.com/blog/2014/10/07/使用AsyncQueryHandler与ContentProvider/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接