ANDROID.RLK.MEDIARECORDER

RLK (リソースリーク) 指摘は、割り当てられたリソースが使用後に適切に破棄されなかった場合に報告されます。ANDROID.RLK.MEDIARECORDER 警告は、開かれた MediaRecorder が明示的に解放されていないことを示します。

脆弱性とリスク

ストリーム、接続、グラフィックオブジェクトなどのリソースは、明示的に閉じられる必要があります。閉じる操作により、トランザクションをアンブロックすることや、ファイルシステム内のファイルの変更をフラッシュすることができます。リソースは、最終的にはガーベッジコレクタにより閉じられますが、ガーベッジコレクションが開始される前にリソースの枯渇が発生する可能性があります。リソースの性質によっては、別のリソース割り当ての失敗時に、さまざまな例外がスローされます。次のような例外があります:java.io.FileNotFoundException:開かれたファイルが多すぎるか、データベース接続が多すぎます。

軽減と防止

重要でないと考えられるリソースであっても、メソッドを持つリソースはすべて明示的に閉じてください。こうすることで、将来的なコード変更時にもこのようなエラーから安全が保たれます。

例 1

コピー
     public boolean onKeyDown(final int keyCode, final KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_ENTER) {
             MediaRecorder recorder = new MediaRecorder();
             recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
             recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
             recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
             recorder.setOutputFile(PATH_NAME);
             recorder.prepare();
             recorder.start();   // Recording is now started
             recorder.stop();
             recorder.reset();   // You can reuse the object by going back to setAudioSource() step
             recorder.release();
             return true;
         }
         return super.onKeyDown(keyCode, event);
     }

ANDROID.RLK.MEDIARECORDER が、行 22 のスニペットについて報告されています。'setAudioSource(...)' から java.lang.IllegalStateException がスロー (23 行目) された場合、「recorder」が終了時に解放されないためです。

例 2

コピー
     public boolean onKeyDown(final int keyCode, final KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_ENTER) {
             MediaRecorder recorder = new MediaRecorder();
             try {
                 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                 recorder.setOutputFile(PATH_NAME);
                 recorder.prepare();
                 recorder.start();   // Recording is now started
                 recorder.stop();
                 recorder.reset();   // You can reuse the object by going back to setAudioSource() step
             } finally {
                 recorder.release();
             }
             return true;
         }
         return super.onKeyDown(keyCode, event);
     }

例 1 のスニペットを修正しました。フィールドは、ANDROID.RLK.MEDIARECORDER は報告されません。

拡張機能

このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、Java 解析のチューニングを参照してください。