java - 致命异常 : AsyncTask caused by ConcurrentModificationException

标签 java android android-asynctask concurrentmodification

我是 Android 新手,一般都在开发,因此非常感谢您的帮助。关于“AsyncTask 中的致命异常”的大多数问题(和答案)都是 NullpointerException,所以我认为我可以提问。

我使用这个 Midi 驱动程序 https://github.com/kshoji/USB-MIDI-Driver从外部键盘获取笔记。我将收到的音符添加到数组中,以便获得播放音符的序列。然后,我使用 AsyncTask 将部分输入与给定的笔记列表进行匹配。 “计算矩阵”和“同步”这两种方法基本上是从一篇关于同步音乐数据的论文中复制(简化)的。

所以我的 Activity 是这样做的:

private void syncInput() {
    if(syncTask.getStatus() != AsyncTask.Status.RUNNING){
        syncTask = new SynchronisationTask(this, synchronizer);
        syncTask.execute();
    }
}

我的 AsyncTask 执行此操作:

public SynchronisationTask(ShowNotesActivity sna, Synchronizer s){
    this.showNotesActivity = sna;
    this.synchronizer = s;
}
@Override
protected Integer doInBackground(Mat... params) {
    return synchronizer.getPosition();
}

我的同步器是这样的:

public int getPosition() {
...
    if(input.size() < 10){
        length = input.size();
    }
    currentPart = partNotes.subList(0, 11);
    currentInput = input.subList(input.size() - length, input.size());

    if(currentPart.size() > 0 && currentInput.size() > 0){
        cost = new int[currentPart.size()][currentInput.size()];
        calculateMatrix();
        sync();
    }
    //not yet sure what I want to return so its 0
    return 0;
}

private void sync() {
    int i = currentPart.size()-1;
    int j = currentInput.size()-1;
    List<Pair<Integer,Integer>> pmMatch = new ArrayList<>();
    while(i > 0 && j > 0){
        if(cost[i][j] == cost[i][j-1]){
            j--;
        }else{
            if(cost[i][j] == cost[i-1][j]){
                i--;
            } else{
                pmMatch.add(Pair.create(i,j));
                i--;
                j--;
            }
        }
    }
    int max = 1;
    for(Pair p : pmMatch){
        if((int)p.first > max)
            max = (int)p.first;
    }
    lastNote = max;
    lastMatch = pmMatch.size();
    match++;
}

private void calculateMatrix(){
    int p = currentPart.size();
    int m = currentInput.size();

    int c = fivePointTwo();
    for(int i = 0; i < p; i++){
        cost[i][0] = c;
    }
    for(int j = 1; j < m; j++){
        cost[0][j] = c;
    }
    for(int i = 1; i < p; i++){
        for (int j = 1; j < m; j++) {
            int d = fivePointFour(currentPart.get(i), currentInput.get(j));
            if(cost[i-1][j-1] + d < Math.min(cost[i-1][j], cost[i][j-1])){
                cost[i][j] = cost[i-1][j-1] + d;
            }
            else if(cost[i-1][j] < cost[i][j-1]){
                cost[i][j] = cost[i-1][j];
            } else{
                cost[i][j] = cost[i][j-1];
            }
        }
    }
}

我的应用程序或多或少地随机崩溃,现在我终于得到了一些信息......我不明白。我希望你能帮助我解决这个错误:

06-08 01:30:18.149  26521-27123/ba.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3
Process: ba.myapplication, PID: 26521
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 android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        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.AbstractList$SubAbstractList.size(AbstractList.java:360)
        at ba.myapplication.Synchronizer.sync(Synchronizer.java:89)

sync(Synchronizer.java:89)是“sync”方法中的第二行:int j = currentInput.size()-1;

最佳答案

getPosition()代码 currentInput = input.subList(input.size() - length, input.size());导致了这个问题。看起来您正在修改 input列出同时 getPosition()工作中。

来自 subList javadoc:

The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

您可以尝试创建输入子列表的副本:currentInput = new ArrayList<>(input.subList(input.size() - length, input.size())); ,或将同步添加到您的代码中。

关于java - 致命异常 : AsyncTask caused by ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30699842/

相关文章:

java - jbdc 忽略 sql 语句中的别名

java - 如何自动点击JOptionPane的OK

java - LibGDX - Scene2d 无法单击小部件

java - Kotlin 中的哪些语言功能可能导致内存泄漏?

java - 异步任务下载的进度条

java - 如何实现用户以安全的方式发布一些 html 格式的数据的可能性?

java - Android 应用在 Android 上播放 HTTP Live Stream 时显示 : "Can' t Play This Video.

android - 如何从Android中的原始文件夹一个接一个地播放音频文件

java - 使用 AsyncTask 从 url 获取文本。代码由于某种原因无法工作

android - 将参数传递给 AsyncTask 构造函数有哪些优点/缺点?