【发布时间】:2017-05-27 13:18:02
【问题描述】:
当我使用 ORMlite 对我的数据库进行一些更新操作时,我有很多 ConcurrentModificationException。我将执行实际更新的代码包装到rx.Observables 中以使其异步进行。看起来像这样:
@Override
public void setFavoriteTeams(List<Team> teams) {
final Iterator<Team> it = teams.iterator();
Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(final Subscriber<? super Object> subscriber) {
try {
List<String> teamIds = new ArrayList<>();
while (it.hasNext()) {
Team team = it.next();
teamIds.add(team.getmSipId());
}
setFavoriteTeamsSql(teamIds);
} catch (Exception e) {
handleException(e);
} finally {
subscriber.onNext(null);
subscriber.onCompleted();
}
}
}).subscribeOn(Schedulers.computation()).subscribe();
}
具有讽刺意味的是,不久前我开始使用 Interator 而不是 for 循环来避免可能发生的任何 ConcurrenceModificationException,但它们反而增加了很多。 setFavoriteTeamsSql(List<String>) 方法只是使用 ORMlite 的 UpdateBuilder 类来更新表。在Team team = it.next(); 行抛出异常。
知道如何解决这个问题吗?现在我正在回滚更改并返回 for 循环。但我希望以正确的方式做到这一点。
更新:
这是 Stacktrace 的样子:
Non-fatal Exception: java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com.siplay.android_siplay.data.cache.db.DBTeamCache$4.call(DBTeamCache.java:164)
at com.siplay.android_siplay.data.cache.db.DBTeamCache$4.call(DBTeamCache.java:157)
at rx.Observable.unsafeSubscribe(Observable.java:10150)
at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$1.call(EventLoopsScheduler.java:172)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
更新 2:
...
mNetworkTeamRepository
.subscribeOn(Schedulers.io())
.obseveOn(AndroidSchedulers.mainThread())
.subscribe(new DefaultSubscriber<List<Teams>>() {
@Override
public void onSuccess(List<Team> teams) {
mTeamsCache.setFavoriteTeams(teams);
}
public void onResult(List<Team> teams) {
callback.showTeams(teams);
}
});
...
TeamRepository 在内部使用 Retrofit 服务来获取服务器端响应。
【问题讨论】:
标签: android sqlite rx-java ormlite concurrentmodification