所以我们在 Parse SDK for Android 中遇到了这个非常奇怪、看似随机的崩溃。通常我们会将此归因于 Parse 平台中的一个错误,但它对我们所有用户的发生非常一致,并且研究该问题并没有发现任何已知原因。事实上,只有一个问题与这个问题有轻微的相关性,可以在这里找到;链接。
基本故障是我们在 Crashlytics 日志中检测到以下崩溃:
Fatal Exception: java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:787)
at java.util.HashMap$KeyIterator.next(HashMap.java:814)
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:960)
at com.parse.ParseTraverser.visit(ParseTraverser.java:100)
at com.parse.ParseTraverser.visit(ParseTraverser.java:94)
at com.parse.ParseTraverser.visit(ParseTraverser.java:101)
at com.parse.ParseTraverser.visit(ParseTraverser.java:94)
at com.parse.ParseTraverser.visit(ParseTraverser.java:101)
at com.parse.ParseTraverser.traverse(ParseTraverser.java:137)
at com.parse.OfflineStore.saveLocallyAsync(OfflineStore.java:776)
at com.parse.OfflineStore.access$200(OfflineStore.java:36)
at com.parse.OfflineStore$38.then(OfflineStore.java:1251)
at com.parse.OfflineStore$38.then(OfflineStore.java:1227)
at bolts.Task$15.run(Task.java:917)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeAfterTask(Task.java:908)
at bolts.Task.continueWithTask(Task.java:715)
at bolts.Task.continueWithTask(Task.java:726)
at bolts.Task$13.then(Task.java:818)
at bolts.Task$13.then(Task.java:806)
at bolts.Task$15.run(Task.java:917)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeAfterTask(Task.java:908)
at bolts.Task.access$100(Task.java:32)
at bolts.Task$11.then(Task.java:708)
at bolts.Task$11.then(Task.java:705)
at bolts.Task.runContinuations(Task.java:956)
at bolts.Task.trySetResult(Task.java:994)
at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
at bolts.Task$15$1.then(Task.java:934)
at bolts.Task$15$1.then(Task.java:921)
at bolts.Task$14.run(Task.java:872)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeImmediately(Task.java:863)
at bolts.Task.continueWith(Task.java:661)
at bolts.Task.continueWith(Task.java:672)
at bolts.Task$15.run(Task.java:921)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeAfterTask(Task.java:908)
at bolts.Task.access$100(Task.java:32)
at bolts.Task$11.then(Task.java:708)
at bolts.Task$11.then(Task.java:705)
at bolts.Task.runContinuations(Task.java:956)
at bolts.Task.trySetResult(Task.java:994)
at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
at bolts.Task$15$1.then(Task.java:934)
at bolts.Task$15$1.then(Task.java:921)
at bolts.Task$14.run(Task.java:872)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeImmediately(Task.java:863)
at bolts.Task.continueWith(Task.java:661)
at bolts.Task.continueWith(Task.java:672)
at bolts.Task$15.run(Task.java:921)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeAfterTask(Task.java:908)
at bolts.Task.access$100(Task.java:32)
at bolts.Task$11.then(Task.java:708)
at bolts.Task$11.then(Task.java:705)
at bolts.Task.runContinuations(Task.java:956)
at bolts.Task.trySetResult(Task.java:994)
at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
at bolts.Task$15$1.then(Task.java:934)
at bolts.Task$15$1.then(Task.java:921)
at bolts.Task$14.run(Task.java:872)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeImmediately(Task.java:863)
at bolts.Task.continueWith(Task.java:661)
at bolts.Task.continueWith(Task.java:672)
at bolts.Task$15.run(Task.java:921)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeAfterTask(Task.java:908)
at bolts.Task.access$100(Task.java:32)
at bolts.Task$11.then(Task.java:708)
at bolts.Task$11.then(Task.java:705)
at bolts.Task.runContinuations(Task.java:956)
at bolts.Task.trySetResult(Task.java:994)
at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
at bolts.Task$15$1.then(Task.java:934)
at bolts.Task$15$1.then(Task.java:921)
at bolts.Task$14.run(Task.java:872)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
at bolts.Task.completeImmediately(Task.java:863)
at bolts.Task.continueWith(Task.java:661)
at bolts.Task.continueWith(Task.java:672)
at bolts.Task$15.run(Task.java:921)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
现在,正如您所看到的,此堆栈跟踪并未向我们显示代码中问题所在的位置,并且我们无法始终如一地重现它。它似乎是随机弹出的,与我链接的上一个问题相反。
有没有人有这个问题的经验?如果是这样,是什么原因造成的?我检查了我们的代码是否在某处循环通过ParseObject
s 列表并删除条目,但我找不到任何发生这种情况的实例。