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);
     }

针对第 22 行的代码段报告 ANDROID.RLK.MEDIARECORDER:如果 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);
     }

前一部分的代码段已修正;ANDROID.RLK.MEDIARECORDER 不会在此处报告。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 Java 分析。