我是Java和Android编程的新手,虽然我做了一些广泛的PHP编码,所以我很快就理解了大多数概念。我不知道的是做事的“方式”。
作为一个练习应用程序,我想编写一个快速傅里叶变换应用程序,它向我展示录制的音频频谱(我是一个物理专业,所以这似乎是一个有价值和有趣的小项目。)(是的,我知道它的之前已经完成了。
到目前为止,我已经设置了AudioRecord阅读器,我让它读取字节,我想我需要创建一个帖子发送给Handler,如果我想让它在后台运行而不冻结应用程序,我想出了如何将数据传递给Handler。现在它只是在MainActivity的TextView中显示字节,所以我可以“看到”正在发生的事情。
我被困住的地方显然是因为我的处理程序不是静态的,在我的应用程序运行几秒钟之后,GC会破坏某些东西(我不知道是什么),并且它会崩溃。经过一些阅读,我似乎已经想通了我需要扩展Handler并实现一些WeakReference,但是,老实说,它已经到了我不知道自己在做什么的地步。如果有人能够解释这里究竟发生了什么,或者我如何从一些外部类中引用我的TextView,我将非常感激。在此先感谢EastWind
以下是代码:
private Handler uiCallback = new Handler () {
public void handleMessage (Message msg) {
tv.setText(Arrays.toString(msg.getData().getByteArray("data")));
}
};
@Override
protected void onResume() {
super.onResume();
tv = (TextView) findViewById(R.id.mainView);
bufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
ar = new AudioRecord(AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
shortbuffer = new short[bufferSize];
bytebuffer = new byte[bufferSize];
ar.startRecording();
tv.setText("Hello");
int N = 0;
// now you can start reading the bytes from the AudioRecord
Thread t = new Thread() {
public void run() {
Bundle b = new Bundle();
Message msg = Message.obtain();
while (true) {
ar.read(bytebuffer, 0, bytebuffer.length);
byte[] pkt = Arrays.copyOf(bytebuffer, bytebuffer.length);
//tv.setText(Arrays.toString(pkt));
b.putByteArray("data", pkt);
msg.setData(b);
uiCallback.sendMessage(msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
t.start();
}
@Override
protected void onPause() {
super.onPause();
ar.stop();
}
答案 0 :(得分:0)
您在循环中多次发送相同的消息,您必须在发送之前获取新消息
答案 1 :(得分:0)
弱引用是一个提示,用于避免访问已从其容器中删除的视图(例如,活动)。
一种可能的替代解决方案是你做这样的事情:
class YourSpecialAudioClass implements ISpecialAudioClass
{
/**this class can be used by the outside UI world, inside the implementation of the runnable in the CTOR*/
@override
public byte[] getData(){...}
public YourSpecialAudioClass(Runnable doSomethingWithDataRunnable)
{
this.doSomethingWithDataRunnable=doSomethingWithDataRunnable;
this.handler=new Handler();
}
...
while(true)
{
...
this.handler.post(this.doSomethingWithDataRunnable);
}
...
}
不要忘记在不需要时阻止线程更新UI,尤其是在活动被关闭的情况下。