0

ListView从本地填充后,SQLite我想通过网络从远程数据库中获取数据以检索新数据,并将其显示在其中,ListView以便本地SQLite数据库只是在没有互联网的情况下的后备方法。

我使用不同Thread的方法将网络获取的数据插入 SQLite,然后重新填充ListView列表。

自然地,应用程序崩溃,因为在某些时候第二个Thread正在删除列表中的每个项目(以添加新项目),并且当时UI Thread正在尝试访问已被辅助线程删除的索引。

由于这是出于学术目的,因此该想法不使用外部/自定义库,那么不包括自定义库的好方法是什么?

4

3 回答 3

1

将数据库包装在内容提供程序中。做起来不难,因为你已经有了数据库。不要编写自己的线程,而是使用 IntentService 获取网络数据并将其写入内容提供程序。

在您的 Activity 中,使用 CursorLoader 在后台从内容提供程序加载数据。CursorLoader 包含 onDataSetChanged() 的实现,因此每次更新内容提供程序时,都会重新加载 Cursor。每次 Cursor 重新加载时,将新的 Cursor 交换到支持 ListView 的 CursorAdapter 中。

要在 IntentService 和您的 Activity 之间进行通信,请做两件事:

  • 当网络下载完成时,从 IntentService 向 Activity 发送本地广播 Intent(使用 LocalBroadcastManager)。如果您的 Activity 在前台,它将立即获得广播,并且您可以第一次启动 CursorLoader。
  • 同时发布来自 IntentService 的通知。在此通知中,包含内容 Intent。如果您的 Activity 在后台并且 IntentService 完成,则用户会看到通知。然后,他或她可以单击通知返回到您的活动。如果需要,您可以关闭 CursorLoader,或者直到 CursorLoader 自动重新启动。

您的问题指出了在 Android 中编程时重新考虑应用程序结构的可取性。Android 应用程序不是线性的;它们更像是根据当前状态相互交互的巨型对象。出于这个原因,您应该避免在一个 Activity 中编写整个应用程序,或者从上到下编写它。

此外,几乎没有理由自己创建一个新的 Thread()。Android 提供了大量为您处理异步处理的类。如果您发现自己在编写 Thread() 或 run(),请小心。

于 2013-09-16T22:48:25.760 回答
0

由于显示的数据ListView是共享的,因此您必须通过同步来保护它。您应该在不同的线程中编写代码synchronized (data) {// data operation}以防崩溃

于 2013-09-17T02:16:43.190 回答
0

仅更新ListView主应用程序线程上的。例如,Thread使用代替 a ,AsyncTask在其中执行磁盘和网络 I/OdoInBackground()并更新ListViewin onPostExecute()

于 2013-09-16T22:33:43.073 回答