0

AsyncTaskユーザーがアプリケーションを強制終了するか、バックグラウンドに移動するときに、使用されているメモリをクリーンアップする方法に少し問題があります。

具体的には、AsyncTaskオーディオ データを記録し、信号をリアルタイムでグラフ化するために を使用しているアプリがあります。記録のために、クラスを使用してAudioRecordいます。このクラスでは、記録を開始してから、記録オブジェクトを停止して解放する必要があります。私の問題は、このオブジェクトを停止して解放する方法がわからないことです。

私が考えて試したオプション:

  1. onPauseonStop、メソッドでオブジェクトの解放を停止しますonDestroyが、これにより例外が発生します。
  2. onPostExecuteのメソッドでオブジェクトを停止して解放しますAsyncTask。これに関する問題は、メソッドが終了しないため、ユーザーが強制的にアプリを終了したときにこのメソッドが呼び出されるかどうかわからないことですdoInBackground。これに関するドキュメントは見つかりませんでした。

AsyncTaskの見た目は次のとおりです。

        AsyncTask<Void, Void, Void> drawer = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            recorder.startRecording();
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            while(true) {
                int nRead = 0;
                int offset = 0;

                while(nRead != readSize) {
                    nRead += recorder.read(buffer, offset + nRead, readSize - nRead);
                }

                for(int i = 0; i < readSize; i++) {
                    data[i] = buffer[i];    
                }

                publishProgress();
            }               
        }

        @Override
        protected void onProgressUpdate(Void... arg0) {
            view.setData(data);
            view.invalidate();
        }
    };

コードはうまく機能します。記録オブジェクトを適切にクリーンアップし、まったくリークしないようにする最善の方法がわかりません。私の混乱は、UI スレッドが一時停止または停止したときにどうなるか、さらに、別のスレッドからオブジェクトAsyncTaskを停止できる場合にどうなるかということです。AudioRecord

どんな助けでも大歓迎です。
ありがとうございました、

4

1 に答える 1

2

OnPostExecuteバックグラウンドループを終了しないため、呼び出されません。ループを終了する条件が必要です。UIで設定した変数を使用して、バックグラウンドタスクをチェックインするか、キャンセル機能を使用できますAsyncTask

たとえば、onPause()メソッドでは、次のコマンドでタスクをキャンセルできます。drawer.cancel(true);

次に、doInBackgroundループで、タスクがキャンセルされているかどうかを確認します。

if (isCancelled()) {
   // clean up here
   break;
} else {
  publishProgress();
}

これは、クリーンアップのためにUIに触れる必要がない限り機能します。UIのクリーンアップを行う必要がある場合は、onCancelledメソッドをオーバーライドできます。

長時間実行されるタスクの場合は、を使用しないことをお勧めしますAsyncTask。したがって、スレッドの使用を検討することをお勧めします。AsyncTask ドキュメントから、

AsyncTasksは、理想的には短い操作(最大で数秒)に使用する必要があります。スレッドを長期間実行し続ける必要がある場合は、java.util.concurrentpacakgeによって提供されるさまざまなAPIを使用することを強くお勧めします。 Executor、ThreadPoolExecutorおよびFutureTask。

于 2013-01-03T19:53:31.800 に答える