使用静态Handler类,引用外部TextView

时间:2013-04-17 17:17:00

标签: android

我是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();
}

2 个答案:

答案 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,尤其是在活动被关闭的情况下。