我正在尝试在我的Android应用中实现流音频,所以我想要做的是从一个线程中的http服务器下载音频文件并将其发送到第二个线程进行解码。为了从第一个线程发送流到第二个线程,我尝试使用不同类型的BlockingQueues甚至是PipedReader和PipedWriter(但这些非常非常慢)。为了测试线程之间的通信,我只需将数据写入第二个线程中的文件,而不是解码mp3数据。
这两个线程由主线程生成(下载线程实际上是一个AsyncTask)。
这是队列,在主线程中创建了final: final BlockingQueue stream = new LinkedBlockingQueue();
AsyncTask的doInBackground():
InputStream input = null;
HttpURLConnection connection = null;
try {
URL url = new URL("http://" + serverIP + "/songs/test.mp3");
connection = (HttpURLConnection) url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();
input = connection.getInputStream();
byte data[] = new byte[CHUNK_SIZE];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
stream.put(new StreamBuffer(data, count));
}
} catch (Exception e) {
return -1;
} finally {
try {
if (output != null) output.close();
if (input != null) input.close();
} catch (Exception e) {
}
if (connection != null)
connection.disconnect();
}
线程2的run():
try {
FileOutputStream outputnf = null;
try {
outputnf = new FileOutputStream(Environment.getExternalStorageDirectory() + "/CCMP/test.mp3");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (true) {
StreamBuffer buff = ((StreamBuffer) stream.take());
if (outputnf != null) {
outputnf.write(buff.buffer, 0, buff.length);
}
}
} catch (Exception e) {
System.out.println(" PipeThread Exception: " + e);
}
StreamBuffer:
public class StreamBuffer
{
byte[] buffer;
int length;
public StreamBuffer(byte[] data, int count) {
buffer = data;
length = count;
}
}
正确下载数据,但是当我查看文件时,它已损坏(某些部分丢失或只是错误)。代码有什么问题?甚至可以在线程之间流式传输整个文件而不会“丢失”吗?不应该吗?我应该重新考虑我的计划结构吗?也许把所有东西放在一个线程? 提前谢谢......
答案 0 :(得分:1)
答案 1 :(得分:0)
好的,我自己解决了这个问题。问题是,lbalazscs建议,所有StreamBuffer元素都使用相同的byte []数组。所以这是我的问题的解决方案:
public class StreamBuffer
{
byte[] buffer;
public StreamBuffer(byte[] data, int count) {
buffer = new byte[count];
System.arraycopy(data, 0, buffer, 0, count);
}
}