我有一个需要从服务器提取数据并将其插入到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线程中运行
。这就是我真正开始将头发撕掉的关键所在,因为这对我完全没有意义。无论我做什么,UI总是在插入过程中挂起。有什么办法让他们不要呢?
与其调用mContentResolver.insert()
,请使用AsyncQueryHandler
及其startInsert()
方法。AsyncQueryHandler
设计用于促进异步ContentResolver
查询。
我有一个ScheduleTimer类,它可以处理日期数组。这是: 如果我像Java应用程序一样运行它,而不是像android一样运行,并且它在控制台中每隔一秒打印一次,那么它就可以正常工作。但是当在android环境中运行它时,它要么说UI线程不能从任何其他线程接触,要么它在类ScheduleTimer的方法中给了我null点异常。 我这样使用它:
在UI线程中运行代码的观点中,以下两者之间有什么区别吗: 或 而且
问题内容: 编辑:我现在确定问题与保存所有其他命令的循环有关, 因为我已将其注释掉,并且在部署应用程序时没有附加的异常。我不确定它有多重要,但是我的实现看起来像这样: 因此,现在该线程在部署应用程序时运行,但是由于注释了循环,因此它没有实际意义。 当我的应用程序加载时,我需要在后台运行一个线程,并不断(无超时)检查某个对象队列。当然,一旦有了对象,它就会“照顾它们”,然后继续检查队列。 目前,我正
我有一个简单的Java代码: 文件夹结构为: 在文件夹中,有和文件。 null null 这里怎么了?
问题内容: 无限期运行,因此该程序永远不会到达终点。不打电话怎么办?(即使我这样称呼,它也会开始运行并转到下一行,不是吗?) 问题答案: 由于尾随的对,你正在运行在错误的线程,在 当前 线程-而不是新线程你创建-并传递 返回值 的的召唤为的说法。期望传递给函数以进行调用,因此只需删除括号并记住启动线程即可: 对于需要参数的目标,可以使用和的参数,也可以使用lambda。例如,要在线程中运行,可以使