如何在访问数据库时管理严格的策略警告

时间:2014-02-09 14:56:03

标签: android multithreading

当我尝试在数据库中插入一些值时,我收到了警告

android.os.StrictMode$StrictModeDiskReadViolation: policy=2079 violation=2
在探索之后我开始知道

  

StrictMode最常用于捕获意外磁盘或网络   访问应用程序的主线程,UI操作在哪里   收到和动画发生。保持磁盘和网络   主线程的操作使得更顺畅

所以现在使用Thread我正在执行数据库插入和删除,如下所示

new Thread(new Runnable() {
            public void run() {


                //insert data into database



            }
          }).start();

但问题是每次某个地方或其他地方我无法创建线程来执行小型小操作。 那么有没有统一或常用的方法来执行这样的数据库任务? 此外,我是否需要跟踪我正在创建的匿名线程?

2 个答案:

答案 0 :(得分:0)

  

问题是每次某个地方或其他地方我都无法创建线程来执行小型小型操作

从主应用程序线程的角度来看,磁盘I / O和网络I / O不是“小型小型操作”。

  

那么有没有统一或常用的方法来执行这样的数据库任务?

根据您的需要,使用ThreadAsyncTaskIntentService等执行数据库操作。

  

此外,我是否需要跟踪我正在创建的匿名线程?

这取决于线程的性质。

获取代码片段,如果//insert data into database只执行此操作,虽然在主应用程序线程上执行需要很长时间,但仍应以毫秒或秒为单位完成。此时,线程将自行终止。只要你没有做任何可能导致线程无限期运行的事情,你可能不需要担心线程本身。

另一种方法是让一个线程不断运行,阻塞工作队列。这可以是HandlerThread,也可以使用类似Thread的常规LinkedBlockingQueue。然后,当您的应用程序的其余部分想要执行某些I / O时,它会向该工作队列发送一条消息,从而导致该线程执行该操作。在这种情况下,你需要确保你完成它后摆脱这个线程,因为它被设计为永远运行,等待更多的工作。不幸的是,可能很难确定您何时完成它。这就是为什么为单个事务(例如,数据库插入集)生成短期一次性线程通常更简单的一个原因。

答案 1 :(得分:0)

CommonsWare的回答是正确的。另一种解决方案是ASyncQueryHandler http://developer.android.com/reference/android/content/AsyncQueryHandler.html

如果您希望在完成时收到通知,可以致电startInsert以异步方式进行插入,并覆盖onInsertComplete

这里有一个'简单'的例子ExpandableList2