AndroidNetworking.post循环发数据后SQLite仅最后一条更新问题求助
Hey,我来帮你捋捋这个问题的排查思路——这种批量请求后只有最后一条数据库更新成功的情况,我之前也碰到过好几次,大概率是并发操作或者变量引用的问题,咱们一步步拆:
1. 先查「变量捕获/引用」的坑
这是最常见的原因!你在循环读取Cursor的5条数据时,是不是复用了同一个对象来存储每条数据?比如循环外定义了一个Ticket对象,每次循环只更新它的属性,然后在onResponse回调里直接引用这个对象。
因为AndroidNetworking的请求是异步的,循环会先跑完,所有回调才会陆续执行,这时候那个复用的对象已经被最后一条数据覆盖了,导致所有回调都拿着最后一条的标识去更新数据库。
验证方法:看你打印的ticket_tick_no_delayed日志,如果日志里全是最后一条的编号,那肯定是这个问题。
解决思路:
- 循环内部每次新建一个
Ticket对象,或者把ticket_tick_no存为循环内的局部变量(用final修饰确保回调能正确捕获),让每个请求的回调绑定自己对应的数据。
举个错误和正确的代码对比:
错误示例(复用对象):
Ticket ticket = new Ticket(); while(c.moveToNext()){ ticket.setTickNo(c.getString(c.getColumnIndex("ticket_tick_no"))); AndroidNetworking.post(url) .addBodyParameter("tick_no", ticket.getTickNo()) .build() .getAsJSONObject(new JSONObjectRequestListener() { @Override public void onResponse(JSONObject response) { // 这里拿到的是最后一次赋值的tick_no updateTicketStatus(ticket.getTickNo()); } }); }正确示例(局部变量捕获):
while(c.moveToNext()){ final String currentTickNo = c.getString(c.getColumnIndex("ticket_tick_no")); AndroidNetworking.post(url) .addBodyParameter("tick_no", currentTickNo) .build() .getAsJSONObject(new JSONObjectRequestListener() { @Override public void onResponse(JSONObject response) { updateTicketStatus(currentTickNo); Log.d("TAG", "ticket_tick_no_delayed: " + currentTickNo); } }); }
2. 排查SQLite更新操作的准确性
如果日志里5条ticket_tick_no都正常打印,但只有最后一条更新成功,那要检查数据库更新代码:
- 确认更新SQL的条件是否正确:比如你的
update语句是不是update tickets set is_send = '1' where ticket_tick_no = ?,参数有没有传对当前的ticket_tick_no?可以把每次执行的SQL语句和参数打印出来,看是不是每条都用了正确的标识。 - 检查数据库操作的线程:如果在UI线程连续执行多个更新,会不会有操作被中断?建议把数据库更新放到单独的线程(比如用AsyncTask或者线程池),确保每个更新都能完整执行。
- 有没有用事务?如果批量更新没有包裹在事务里,前面的更新可能因为某种原因没有提交,不过这种情况一般是全失败或者部分失败,你只有最后一条成功的话概率低,但也可以试试把更新操作放到事务里。
3. 确认请求是否真的全部成功
虽然你说API响应成功,但还是要确认5条请求都走到了onResponse:
- 检查
onError回调有没有被触发,会不会前面的请求其实失败了只是你没注意?可以在onError里也打印日志,看看有没有请求报错。 - 查看网络请求的日志(比如用Charles抓包),确认服务器确实返回了5次成功响应。
4. 检查Cursor的处理是否正确
有没有在循环结束后正确关闭Cursor?如果Cursor没有关闭,会不会导致数据库连接异常,影响前面的更新操作?记得在finally块里调用c.close()释放资源。
内容的提问来源于stack exchange,提问作者user9064724
相关产品推荐
相关产品推荐

