Android(安卓)Sqlite ANR 问题解决及其事物处理 -- waiting on (a java.lang.VMThread) held by tid=1 (main)
16lz
2021-01-24
错误日志
The connection pool for database '/data/data/com.meelive.ingkee/databases/Ingkee45997756' has been unable to grant a connection to thread 1 (main) with flags 0x5 for 30.000002 seconds. Connections: 0 active, 1 idle, 0 available.
"main" prio=5 tid=1 · | group="main" sCount=1 dsCount=0 obj=0x41ad2de0 self=0x41a86130 | sysTid=3866 nice=0 sched=0/0 cgrp=default handle=1074348420 | state=S schedstat=( 22153833728 1885119937 37454 ) utm=1925 stm=290 core=0 at java.lang.Object.wait(Native Method) - waiting on <0x41ad2eb0> (a java.lang.VMThread) held by tid=1 (main) at java.lang.Thread.parkFor(Thread.java:1212) 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:672) at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348) at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894) at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:586) at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58) at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37) at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1364) at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1303) at com.meelive.ingkee.db.a.c(ContactDao.java:100) at com.***.***.v1.chat.model.chat.k.b(JsonToBean.java:157) at com.***.***.v1.chat.model.chat.e$b.a(ChatEventManagerImpl.java:558) at com.loopj.android.http.q.a(TextHttpResponseHandler.java:98) at com.loopj.android.http.c.a(AsyncHttpResponseHandler.java:371) at com.loopj.android.http.c$a.handleMessage(AsyncHttpResponseHandler.java:195) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5468) 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:860) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:676) at dalvik.system.NativeStart.main(Native Method)
1、数据库要去请求锁 但是VMThread持有着 所以在等待
2、beginTransaction();…1…execSQL(sql);….2……endTransaction(); 在2初又执行了查询数据库操作引起的。
解决方法:在endTransaction();后再执行查询操作
stackoverflow 相关问题
这是原来的数据库操作代码
try { - DbManager.getInstance().db.beginTransaction(); for (int i = 0; i < list.size(); i++) { DbManager.getInstance().db.execSQL("delete from " + FEED_LOCAL_VIDEO_TABLE + " where id=" + list.get(i).id); } DbManager.getInstance().db.setTransactionSuccessful(); - DbManager.getInstance().db.endTransaction(); } catch (Exception e) { e.printStackTrace(); }
下面说一下SQLite中的事物处理
使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction()
方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful()
方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful()
方法则回滚事务。事务处理应用:很多时候我们需要批量的向Sqlite中插入大量数据时,单独的使用添加方法导致应用响应缓慢,
因为sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。如初始8000条记录也就是要8000次读写磁盘操作。同时也是为了保证数据的一致性,避免出现数据缺失等情况。
下面是正确的使用方法
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();//开启事务db.beginTransaction();try{ //批量处理操作 //do something db.execSQL("SQL语句", new Object[]{}); db.execSQL("SQL语句", new Object[]{}); //设置事务标志为成功,当结束事务时就会提交事务 db.setTransactionSuccessful();}catch(Exception e){}finally{ //结束事务 db.endTransaction();}
上面的代码修改如下
+ DbManager.getInstance().db.beginTransaction(); try { for (int i = 0; i < list.size(); i++) { DbManager.getInstance().db.execSQL("delete from " + FEED_USER_INFO_TABLE + " where uid=" + list.get(i).uid); } DbManager.getInstance().db.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); return null; + }finally { + DbManager.getInstance().db.endTransaction(); }
更多相关文章
- Android:intent用法实例
- Android(3) 注册界面点击返回登录界面并传值
- 使用RecyclerView加载不出数据的原因可能有:
- android 事务
- Android:onNewIntent()触发机制及注意事项
- js 判断手机操作系统(ios或Android)
- Android之SharedPreferences数据保存
- Android(安卓)读取doc文件
- Android之SharedPreferences对参数数据的存取