ContentProvider insert()始终在UI线程上运行吗?

我有一个需要从服务器提取数据并将其插入到SQLite数据库中以响应用户输入的应用程序。我认为这将非常简单-

从服务器提取数据的代码是AsyncTask的一个非常简单的子类,并且它的工作原理完全符合我的预期,而无需挂起UI线程。我使用一个简单的接口为其实现了回调功能,并将其包装在静态类中,因此我的代码如下所示:

MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() {

@Override

public void onFolderContentsResponse(final List<FilesystemEntry> contents) {

// do something with contents

}

}

一切还不错。即使服务器花费一个小时来检索数据,UI仍然可以平稳运行,因为getFolderContents中的代码在AsyncTask的doInBackground方法中运行(该方法位于与UI分开的线程中)。在getFolderContents方法的最后,调用onFolderContentsResponse并传递从服务器接收的FilesystemEntry的列表。我只是真的说了所有这些,以便希望可以清楚地知道我的问题不在getFolderContents方法或我的任何网络代码中,因为它从来没有发生过。

当我尝试通过onFolderContentsResponse方法中的ContentProvider的子类插入数据库时​​,就会出现问题。在执行该代码时,UI总是挂起,这使我相信,尽管从AsyncTask的doInBackground方法调用了该插入,但是它们仍在UI线程上运行。有问题的代码如下所示:

MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() {

@Override

public void onFolderContentsResponse(final List<FilesystemEntry> contents) {

insertContentsIntoDB(contents);

}

}

insertContentsIntoDB方法:

void insertContentsIntoDB(final List<FilesystemEntry> contents) {

for (FilesystemEntry entry : contents) {

ContentValues values = new ContentValues();

values.put(COLUMN_1, entry.attr1);

values.put(COLUMN_2, entry.attr2);

// etc.

mContentResolver.insert(MyContentProvider.CONTENT_URI, values);

}

}

其中mContentResolver先前已设置为getContentResolver()方法的结果。

我尝试将insertContentsIntoDB放在其自己的线程中,如下所示:

MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() {

@Override

public void onFolderContentsResponse(final List<FilesystemEntry> contents) {

new Thread(new Runnable() {

@Override

public void run() {

insertContentsIntoDB(contents);

}

}).run();

}

}

我还尝试过在其自己的线程中运行每个单独的插入(MyContentProvider中的insert方法是同步的,因此不会在此处引起任何问题):

void insertContentsIntoDB(final List<FilesystemEntry> contents) {

for (FilesystemEntry entry : contents) {

new Thread(new Runnable() {

@Override

public void run() {

ContentValues values = new ContentValues();

values.put(COLUMN_1, entry.attr1);

values.put(COLUMN_2, entry.attr2);

// etc.

mContentResolver.insert(MyContentProvider.CONTENT_URI, values);

}

}).run();

}

}

出于很好的考虑,我还在另一个AsyncTask的doInBackground方法中用相关代码尝试了这两种解决方案。最后,我在AndroidManifest.xml中将MyContentProvider明确定义为处于单独的进程中:

<provider android:name=".MyContentProvider" android:process=":remote"/>

它运行正常,但

。这就是我真正开始将头发撕掉的关键所在,因为这对我完全没有意义。无论我做什么,UI总是在插入过程中挂起。有什么办法让他们不要呢?

回答:

与其调用mContentResolver.insert(),请使用AsyncQueryHandler及其startInsert()方法。AsyncQueryHandler设计用于促进异步ContentResolver查询。

以上是 ContentProvider insert()始终在UI线程上运行吗? 的全部内容, 来源链接: utcz.com/qa/402443.html

回到顶部