Android Observable / AsyncTask等待直到循环结束才执行

时间:2014-10-30 14:14:54

标签: java android

我正在从输入流中读取文本行(当前是文本文件,最终通过蓝牙)

这些行被包装在bufferItem中并被添加到一个缓冲区(ArrayList)中,该缓冲区是Observable&触发器

setChanged();
notifyObservers(item);

Observer上的update方法会为每个缓冲项触发AsyncTask。

因为我的输入流基本上是无穷无尽的,所以我想要的是所有这些同时发生(即数据在新数据也实时到达时被处理),但我所做的是什么?我发现asyncTasks不会启动,直到整个文件被读取。

文件读取位如下:

while (((inputLine = bufferedReader.readLine()) != null)) {

    if (inputLine.substring(0,1).equals("$")){
    bufferItem bi = new bufferItem();
    bi.addItem(inputLine);
        for (int i = 1; i < repeatRate; i++) {
            bi.addItem(bufferedReader.readLine());
        }
    // adding to buffer triggers the observer
    buffer.addItem(bi);
    }
}

整个Observable / Observer进程正在运行,但在读取整个输入文件之后,所有下游进程都没有启动。

我使用类似于以下行的方式监控它:

System.out.println("Item added to buffer");

在一个项目被添加到缓冲区的点处有一个println,而在asyncTask中的一个下游进程中有一个println

所以我将所有&#39;项目添加到缓冲区&#39;首先是行,然后是下游流程日志行,当我希望它们穿插时。

所以问题是(我认为) - 为什么它等到循环完成后再执行notifyObservers()指令呢?

2 个答案:

答案 0 :(得分:1)

似乎数据包/行的顺序很重要,所以:

  1. 接收器线程以块的形式读取输入,将它们添加到输入缓冲区队列中。

  2. 处理器线程,用于查看输入队列,处理项目并将它们放入输出缓冲区队列。如果输入队列为空,则该线程等待接收器将某些内容放入队列并通知它。

  3. 最后,调度程序线程将已处理的项目从输出缓冲区队列中发送/写入/保存/等。如果输出队列为空,则此线程等待处理器将某些内容放入队列并通知它。

  4. 你需要对缓冲区队列有一个上限,所以它们在满时就会阻塞,否则你可能会用完RAM。还要确保由于任何线程错误而导致流量未被阻止。

答案 1 :(得分:0)

看起来这与Honeycomb(及其后)处理AsyncTask的方式有关 - 将AsyncTasks放在同一个线程上,并且与我最初想到的Observer模式无关。

为了使它工作,我将文件读取代码移动到一个单独的AsyncTask并将其称为:

task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

这允许处理文件数据的AsyncTasks立即启动。

如果他们反过来以'标准'的方式被召唤

new Task(param1, param2).execute();

然后它们将按顺序运行。

它们也可以这样称呼:

new Task(param1, param2).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

在这种情况下,它们也将并行运行,但不会按照正在读取的文件的数据顺序运行。如果您需要使用与文件中出现的顺序相同的顺序打包文件数据,这一点非常重要。

这篇文章是关键:

http://www.techrepublic.com/blog/software-engineer/android-asynctask-behavior-changes-you-should-know/

此外,Android文档 - 向下滚动到执行顺序

http://developer.android.com/reference/android/os/AsyncTask.html