先來一段代碼看看:
@Override
protected void onDestroy() {
super.onDestroy();
if (mCaptureRequest != null) {
mCaptureRequest.removeTarget(mSurface);
mCaptureRequest = null;
}
if (mSurface != null) {
mSurface.release();
mSurface = null;
}
if (mSurfaceTexture != null){
mSurfaceTexture.release();
mSurfaceTexture = null;
}
if (mCameraCaptureSession != null) {
try {
mCameraCaptureSession.stopRepeating();
mCameraCaptureSession.abortCaptures();
} catch (CameraAccessException e) {
e.printStackTrace();
}
mCameraCaptureSession = null;
}
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
if (mChildHandler != null) {
mChildHandler.removeCallbacksAndMessages(null);
mChildHandler = null;
}
if (mHandlerThread != null) {
mHandlerThread.quitSafely();
mHandlerThread = null;
}
mCameraManager = null;
mSessionStateCallback = null;
mSessionCaptureCallback = null;
mStateCallback = null;
}
從上面的代碼中可以看出,在destroy時,需要關閉相機相關的資源,並且一定要注意關閉的順序,如果處理不當就面臨的麻煩可能就是內存泄露,注意要釋放的資源,否則一直持有會導致內存泄露.
一般情況下會有以下幾個操作導致內存泄露:
- CaptureRequest 如果沒有釋放Surface, 一定操作釋放 mCaptureRequest.removeTarget(mSurface);
- SurfaceTexture 需要被釋放,除了 mSurfaceTexture.release();
也可以用這種mTextureView.getSurfaceTextureListener().onSurfaceTextureDestroyed(mTextureView.getSurfaceTexture());方式釋放SurfaceTextur,但是在上面的public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) 回調中你需要返回true或者自己執行 surface.release(); 這樣纔會運行onSurfaceTextureDestroyed回調 - Surface 需要被釋放
- 釋放是需要按順序一個一個釋放的
- 如果你想實現一個工具類來以建造者模式來創建相機拍照,請注意TextureView不能傳入工具類裏,因爲你需要實現setSurfaceTextureListener監聽,而這個監聽你是無法在工具類裏釋放它的,它是需要在activity裏才能被釋放,請切記!
你最好只傳入SurfaceTexture給工具類