我正在从输入流中读取文本行(当前是文本文件,最终通过蓝牙)
这些行被包装在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()指令呢?
答案 0 :(得分:1)
似乎数据包/行的顺序很重要,所以:
接收器线程以块的形式读取输入,将它们添加到输入缓冲区队列中。
处理器线程,用于查看输入队列,处理项目并将它们放入输出缓冲区队列。如果输入队列为空,则该线程等待接收器将某些内容放入队列并通知它。
最后,调度程序线程将已处理的项目从输出缓冲区队列中发送/写入/保存/等。如果输出队列为空,则此线程等待处理器将某些内容放入队列并通知它。
你需要对缓冲区队列有一个上限,所以它们在满时就会阻塞,否则你可能会用完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);
在这种情况下,它们也将并行运行,但不会按照正在读取的文件的数据顺序运行。如果您需要使用与文件中出现的顺序相同的顺序打包文件数据,这一点非常重要。
这篇文章是关键:
此外,Android文档 - 向下滚动到执行顺序
http://developer.android.com/reference/android/os/AsyncTask.html