Android Loader应用程序无响应

时间:2014-06-25 15:56:03

标签: android android-contentprovider loader

我在我的Android应用程序中得到一个ANR,我找不到问题。使用严格模式我得到了这个例外:

StrictMode policy violation; ~duration=2 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=2
        at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1107)
        at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1034)
        at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:835)
        at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
        at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
        at android.database.CursorWrapper.getCount(CursorWrapper.java:57)
        at android.support.v4.widget.CursorAdapter.getCount(CursorAdapter.java:202)
        at com.nhaarman.listviewanimations.BaseAdapterDecorator.getCount(BaseAdapterDecorator.java:69)
        at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:801)
        at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:5958)
        at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
        at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
        at android.support.v4.widget.CursorAdapter$MyDataSetObserver.onChanged(CursorAdapter.java:473)
        at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
        at android.database.AbstractCursor.requery(AbstractCursor.java:137)
        at android.database.sqlite.SQLiteCursor.requery(SQLiteCursor.java:225)
        at android.database.CursorWrapper.requery(CursorWrapper.java:186)
        at android.support.v4.widget.CursorAdapter.onContentChanged(CursorAdapter.java:449)
        at android.support.v4.widget.CursorAdapter$ChangeObserver.onChange(CursorAdapter.java:465)
        at android.database.ContentObserver.onChange(ContentObserver.java:129)
        at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:180)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5041)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
        at dalvik.system.NativeStart.main(Native Method)

该应用程序执行以下操作:

  1. 启动Intent服务并抓取一些Feed。
  2. 通过内容提供商将Feed保留到数据库。
  3. 该片段有一个加载程序,当写入发生时会收到通知
  4. 加载程序读取新数据,将其传递给游标适配器并显示它。
  5. 然而,当读取发生时,有时我得到一个ANR,从我理解的堆栈跟踪,光标重新查询数据库,如果它花了太长时间我得到一个ANR,但是我虽然Loaders做了操作异步。我不知道如何解决这个问题。

    我初始化适配器时将“自动查询”标志设置为false,这很重要。

    使用android 4.4

2 个答案:

答案 0 :(得分:0)

您需要在后台线程上执行数据库事务。您在主线程上执行此操作,因此出现严格模式错误。您可以使用AsyncTask并在doInBackground()方法中执行事务。

答案 1 :(得分:0)

如果使用游标适配器,请确保在构造函数中不向其传递autoRequery标志。如果传递true,那么适配器将调用Cursor.requery(),这是错误的,因为这个调用将在UI线程中触发。同样在并行线程中,CursorLoader将选择数据。因此,如果您将从CursorAdapter中删除autoRequery标志,则问题就会消失。我不知道为什么这个构造函数不被弃用但我们拥有的东西。