使用greenDAO获得例外/ ANR

时间:2014-10-23 09:37:00

标签: android sqlite dao greendao

我有一个很大的问题!一些正在使用我的应用程序的人正在进行ANR(应用程序没有响应),当他们正在进行数据库操作时(比如将对象更新到数据库),而正在运行具有数据库读取的(意图)服务。

详细信息:

我正在使用Application-Desgin的单实例模式。这意味着SQLiteOpenHelper的给定上下文是ApplicationContext 块操作是:

ArrayList<Workposition> web_list = (ArrayList<Workposition>) sessionDAO
                    .getWorkpositionDao().queryBuilder().list();

sessionDAO.getWorkpositionDao().update(plantevent);

两个sessionDao都使用带有ApplicationContext的SQLLiteHelper。第一个读取操作发生在后台,第二个操作发生在onClick方法

如果您有兴趣阅读ANR,那么最重要的内容如上所列。 上面提到的代码行在EventView和Workposition中。

    ----- pid 23262 at 2014-10-21 07:58:59 -----
Cmd line: de.myApp

JNI: CheckJNI is off; workarounds are off; pins=0; globals=293

DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)

"main" prio=5 tid=1 WAIT
| group="main" sCount=1 dsCount=0 obj=0x41806ea0 self=0x416fcb78
| sysTid=23262 nice=0 sched=0/0 cgrp=apps handle=1073869140
| state=S schedstat=( 0 0 0 ) utm=306 stm=55 core=1
at java.lang.Object.wait(Native Method)
- waiting on <0x41806f70> (a java.lang.VMThread) held by tid=1 (main)
at java.lang.Thread.parkFor(Thread.java:1205)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:813)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:846)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1175)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:180)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)
at de.greenrobot.dao.identityscope.IdentityScopeLong.put2(IdentityScopeLong.java:85)
at de.greenrobot.dao.identityscope.IdentityScopeLong.put(IdentityScopeLong.java:76)
at de.greenrobot.dao.identityscope.IdentityScopeLong.put(IdentityScopeLong.java:31)
at de.greenrobot.dao.AbstractDao.attachEntity(AbstractDao.java:695)
at de.greenrobot.dao.AbstractDao.updateInsideSynchronized(AbstractDao.java:680)
at de.greenrobot.dao.AbstractDao.update(AbstractDao.java:654)
at de.myApp.views.EventView$1.run(EventView.java:122)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)

"IntentService[a]" prio=5 tid=13 TIMED_WAIT
| group="main" sCount=1 dsCount=0 obj=0x42e28460 self=0x7b5302c0
| sysTid=23337 nice=0 sched=0/0 cgrp=apps handle=2005620856
| state=S schedstat=( 0 0 0 ) utm=7309 stm=180 core=0
at java.lang.Object.wait(Native Method)
- waiting on <0x42c4b8f8> (a java.lang.VMThread) held by tid=13 (IntentService[a])
at java.lang.Thread.parkFor(Thread.java:1205)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:197)
at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:739)
at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:400)
at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:905)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
at android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)
at de.greenrobot.dao.AbstractDao.loadAllFromCursor(AbstractDao.java:392)
at de.greenrobot.dao.AbstractDao.loadAllAndCloseCursor(AbstractDao.java:184)
at de.greenrobot.dao.InternalQueryDaoAccess.loadAllAndCloseCursor(InternalQueryDaoAccess.java:21)
at de.greenrobot.dao.query.Query.list(Query.java:121)
at de.greenrobot.dao.query.QueryBuilder.list(QueryBuilder.java:374)
at de.myApp.modelDAO.Workposition.upload(Workposition.java:588)
at de.myApp.service.ApiService.update(ApiService.java:138)
at de.myApp.service.ApiService.onHandleIntent(ApiService.java:51)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.os.HandlerThread.run(HandlerThread.java:61)

"Binder_3" prio=5 tid=11 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x42fc7e68 self=0x778c0300
| sysTid=23306 nice=0 sched=0/0 cgrp=apps handle=2006715504
| state=S schedstat=( 0 0 0 ) utm=0 stm=0 core=1
#00 pc 0002072c /system/lib/libc.so (__ioctl+8)
#01 pc 0002cec3 /system/lib/libc.so (ioctl+14)
#02 pc 0001d3ed /system/lib/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+140)
#03 pc 0001daf7 /system/lib/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+6)
#04 pc 0001db8d /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+48)
#05 pc 000219e9 /system/lib/libbinder.so
#06 pc 0000ea5d /system/lib/libutils.so (android::Thread::_threadLoop(void*)+216)
#07 pc 00052299 /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+68)
#08 pc 0000e58f /system/lib/libutils.so
#09 pc 0000d278 /system/lib/libc.so (__thread_entry+72)
#10 pc 0000d410 /system/lib/libc.so (pthread_create+240)
at dalvik.system.NativeStart.run(Native Method)

"AsyncTask #1" prio=5 tid=10 WAIT
| group="main" sCount=1 dsCount=0 obj=0x42e06f38 self=0x778c2768
| sysTid=23301 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=2005674944
| state=S schedstat=( 0 0 0 ) utm=29 stm=5 core=2
at java.lang.Object.wait(Native Method)
- waiting on <0x42e070d0> (a java.lang.VMThread) held by tid=10 (AsyncTask #1)
at java.lang.Thread.parkFor(Thread.java:1205)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2017)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1097)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

"pool-1-thread-1" prio=5 tid=12 WAIT
| group="main" sCount=1 dsCount=0 obj=0x42ca18e0 self=0x79564280
| sysTid=23281 nice=0 sched=0/0 cgrp=apps handle=2035697368
| state=S schedstat=( 0 0 0 ) utm=1 stm=1 core=2
at java.lang.Object.wait(Native Method)
- waiting on <0x42ca1a28> (a java.lang.VMThread) held by tid=12 (pool-1-thread-1)
at java.lang.Thread.parkFor(Thread.java:1205)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2017)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1097)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

"Binder_2" prio=5 tid=9 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x42a3f878 self=0x7255dc60
| sysTid=23273 nice=0 sched=0/0 cgrp=apps handle=1918229016
| state=S schedstat=( 0 0 0 ) utm=0 stm=0 core=0
#00 pc 0002072c /system/lib/libc.so (__ioctl+8)
#01 pc 0002cec3 /system/lib/libc.so (ioctl+14)
#02 pc 0001d3ed /system/lib/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+140)
#03 pc 0001daf7 /system/lib/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+6)
#04 pc 0001db8d /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+48)
#05 pc 000219e9 /system/lib/libbinder.so
#06 pc 0000ea5d /system/lib/libutils.so (android::Thread::_threadLoop(void*)+216)
#07 pc 00052299 /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+68)
#08 pc 0000e58f /system/lib/libutils.so
#09 pc 0000d278 /system/lib/libc.so (__thread_entry+72)
#10 pc 0000d410 /system/lib/libc.so (pthread_create+240)
at dalvik.system.NativeStart.run(Native Method)

我不知道为什么会出现这个问题。是因为单一实例吗?如果我会使用两种不同的背景,它会起作用吗?或者我应该在后台线程中执行更新?

2 个答案:

答案 0 :(得分:1)

运行启用了StrictMode的应用,看看你在UI线程上进行长时间运行的操作,然后将这些操作移到AsyncTask或其他东西。

答案 1 :(得分:1)

您永远不应该在主线程上访问数据库。许多数据库操作使用单个锁,因此当您执行此操作时,任何长时间运行的后台查询都可能会阻止您的主线程。由于后台任务的优先级较低,因此很容易导致ANR。 除此之外,磁盘访问可能因任何随机原因(例如,播放商店更新应用程序)而变慢。你真的不想依赖你的UI(不要忘记,你的UI只有16毫秒)。

在此ANR中,后台线程已经具有Identity Scope锁,等待获取SqliteConnection,而主线程被Green Dao的Identity Scope锁阻塞。没有什么能说明为什么数据库需要提供很多连接(ANR中是否有任何其他线程没有显示?)。

确保您永远不会在主线程上访问数据库。 (写或读,无关紧要)。我相信系统最终会解决这个冲突(例如最终会有连接)