5

背景として、マイクを介して継続的に記録し、データをバッファに保存するアプリケーションを作成しようとしています。プログラムの目標は、バッファ内のデータに対して何らかの処理を実行し、それに基づいて動作することです。現在、アプリはデータをバッファに読み込み、できるだけ早く書き込むだけです。アプリを実行すると、マイクに向かって話すと、今話したことを反対側から聞くことができます。

ここで、私の Android の経験不足が頭をよぎり始めます。無限ループとして読み書き操作を行っています。サービスは以下です。

public class AudioService extends Service {

private final int MIC = AudioSource.MIC;
private final int SAMPLE = 44100;
private final int CHANNELI = AudioFormat.CHANNEL_IN_MONO;
private final int CHANNELO = AudioFormat.CHANNEL_OUT_MONO;
private final int FORMAT = AudioFormat.ENCODING_PCM_16BIT;
private final int BUFFERSIZE = AudioRecord.getMinBufferSize(SAMPLE,
        CHANNELI, FORMAT);
private final int STREAM = AudioManager.STREAM_MUSIC;
private final int MODE = AudioTrack.MODE_STREAM;
private boolean play = true;

AudioRecord recorder = null;
AudioTrack track = null;

short[] buffer = null;

public void OnCreate() {

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    recorder = new AudioRecord(MIC, SAMPLE, CHANNELI, FORMAT, BUFFERSIZE);
    track = new AudioTrack(STREAM, SAMPLE, CHANNELO, FORMAT, BUFFERSIZE,
            MODE);
    buffer = new short[BUFFERSIZE];
    recorder.startRecording();
    track.play();

    while (play) {
        recorder.read(buffer, 0, buffer.length);
        track.write(buffer, 0, buffer.length);
    }
    return START_STICKY;
}

このサービスは、アクティビティで「記録」ボタンがクリックされたときに呼び出されます。記録をクリックして、キャンセルをクリックしてこのループを停止できるようにしたいと考えています。これを実装する以下のリスナーは次のとおりです。

private OnClickListener Recording = new OnClickListener() {
    public void onClick(View v) {

        serviceIntent = new Intent(getApplicationContext(),
                AudioService.class);
        serviceIntent.putExtra("extraData", "somedata");
        startService(serviceIntent);

        record.setEnabled(false);
        cancel.setEnabled(true);
        cancel.requestFocus();

};

そして今、問題が明らかになります。アプリケーションは、startService(serviceIntent) に到達した時点で実行を完了できず、残りの部分でぶらぶらしています。

それで、私の頼りになるのは何ですか?無限ループ内からサービスを制御する方法を考えていましたが、Android の経験が浅いため、どうすればよいのか疑問に思っています。ループ内で新しいボタンをインスタンス化することで、なんらかのブレーク方法を誘発します。そのため、startIntent 中にループから抜け出し、「狂気を終わらせる」ことができます。

どんな助けでも大歓迎です。また、「アプリが応答していません...」という問題を回避するために、このサービスを UI とは別のスレッドで開始する必要があることも認識していますが、それは別のトピックです。現在の私の主な目標は、ループから抜け出すことです。これを行う方法についての助けや指示をいただければ幸いです。

4

1 に答える 1

5

サービスは以下

問題 #1: ループから抜け出す方法がない。

問題 #2: ループがメイン アプリケーション スレッドで実行されています。

これは悪いです。

それで、私の頼りになるのは何ですか?

バックグラウンド スレッドに無限ループを配置し、AtomicBoolean必要に応じて停止するようにそのスレッドに指示する何か (たとえば ) を使用します (たとえばonDestroy())。

また、「アプリが応答していません...」という問題を回避するために、このサービスを UI とは別のスレッドで開始する必要があることも認識していますが、それは別のトピックです。

いいえ、同じ話題です。

ループ内で新しいボタンをインスタンス化することで、ブレークする方法を扇動する

サービスには UI がありません。

そのアクティビティには への呼び出しをトリガーする「記録」ボタンがあるためstartService()、おそらくそのアクティビティには への呼び出しをトリガーする「停止」ボタンが必要stopService()です。

をどこでどのように呼び出すかを決定したら、サービスをstopService()取得onDestroy()してバックグラウンド スレッドの実行を停止させるだけです。バックグラウンド スレッドonDestroy()は の呼び出しによってトリガーされますstopService()

于 2012-05-31T23:52:59.230 に答える