如果 SurfaceView 已被销毁,如何重新创建
SurfaceView how to Re-Create if it has been destroyed
我通过 SurfaceView 创建了一个相机,但是当我按下主页并再次返回 activity 时。 SurfaceView 不再显示任何内容。它没有调用
surfaceCreated(SurfaceHolder holder)
而我又回到了activity。我该怎么办?
这是我用 Kotlin 写的代码
class MyCameraView : SurfaceView ,
SurfaceHolder.Callback,Camera.PreviewCallback,Camera.FaceDetectionListener {
private lateinit var mCamera : Camera
var sizes : List<Camera.Size>? = null
constructor( ctx : Context, attrs : AttributeSet?) : super(ctx,attrs){
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(this)
}
constructor(ctx : Context):this(ctx,null){}
override fun surfaceChanged(p0: SurfaceHolder?, format: Int, width: Int, height: Int) {
Log.e("MyCameraView","CHANGE ")
val sizes = mCamera.parameters.supportedPreviewSizes
val size = getOptimalSzie(sizes)
val supportWith = size.height
val supportHeight : Int = size.width
val radio : Float = width.toFloat()/supportWith
setMeasuredDimension(width,(supportHeight*radio).toInt())
layout(0, (-(supportHeight*radio)/5).toInt(),width, ((supportHeight*radio).toInt()-(supportHeight*radio)/5).toInt())
}
override fun surfaceDestroyed(p0: SurfaceHolder?) {
Log.e("MyCameraView","DESTORY")
holder.removeCallback(this)
mCamera.setPreviewCallback(null)
mCamera.stopFaceDetection()
mCamera.stopPreview()
mCamera.lock()
mCamera.release()
}
override fun surfaceCreated(p0: SurfaceHolder?) {
Log.e("MyCameraView","OPEN")
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT)
mCamera.setDisplayOrientation(90)
mCamera.setPreviewCallback(this)
mCamera.setPreviewDisplay(holder)
mCamera.setFaceDetectionListener(this)
mCamera.startPreview();
mCamera.startFaceDetection()
}
private fun getOptimalSzie(sizes: List<Camera.Size>): Camera.Size {
var pos = 0
var ratio = 0
var viewRatio = height/width
sizes.forEachIndexed { index, size ->
val curRatio = size.width/size.height
if(ratio == 0 ) ratio = curRatio
else if( (viewRatio - curRatio) < (viewRatio - ratio) ){
ratio = curRatio
pos = index
}
}
return sizes[pos]
}
override fun onPreviewFrame(data: ByteArray?, camera: Camera) {
if(allowTake) {
val parameters = camera.getParameters()
val width = parameters.previewSize.width
val height = parameters.previewSize.height
val yuv = YuvImage(data, parameters.previewFormat, width, height, null)
val out = ByteArrayOutputStream()
yuv.compressToJpeg(Rect(0, 0, width, height), 50, out)
val bytes = out.toByteArray()
val b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
detected?.invoke(bytes)
allowTake = false
hasTake = true
}
}
var hasTake = false
private var allowTake = false
override fun onFaceDetection(faces: Array<out Camera.Face>?, camera: Camera?) {
if(!hasTake) {
allowTake = true
}
}
private var detected: ((bitmap : ByteArray) -> Unit)? = null
fun onFaceDetected(detected : ( bitmap : ByteArray )->Unit){
this.detected = detected
}
}
我喜欢它!我改为使用 TextureView。它有四种回调方法。这是其中之一
onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int)
当我回到 activity 时被调用了!!!
这样我回来的时候就可以打开相机了
我通过 SurfaceView 创建了一个相机,但是当我按下主页并再次返回 activity 时。 SurfaceView 不再显示任何内容。它没有调用
surfaceCreated(SurfaceHolder holder)
而我又回到了activity。我该怎么办?
这是我用 Kotlin 写的代码
class MyCameraView : SurfaceView ,
SurfaceHolder.Callback,Camera.PreviewCallback,Camera.FaceDetectionListener {
private lateinit var mCamera : Camera
var sizes : List<Camera.Size>? = null
constructor( ctx : Context, attrs : AttributeSet?) : super(ctx,attrs){
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(this)
}
constructor(ctx : Context):this(ctx,null){}
override fun surfaceChanged(p0: SurfaceHolder?, format: Int, width: Int, height: Int) {
Log.e("MyCameraView","CHANGE ")
val sizes = mCamera.parameters.supportedPreviewSizes
val size = getOptimalSzie(sizes)
val supportWith = size.height
val supportHeight : Int = size.width
val radio : Float = width.toFloat()/supportWith
setMeasuredDimension(width,(supportHeight*radio).toInt())
layout(0, (-(supportHeight*radio)/5).toInt(),width, ((supportHeight*radio).toInt()-(supportHeight*radio)/5).toInt())
}
override fun surfaceDestroyed(p0: SurfaceHolder?) {
Log.e("MyCameraView","DESTORY")
holder.removeCallback(this)
mCamera.setPreviewCallback(null)
mCamera.stopFaceDetection()
mCamera.stopPreview()
mCamera.lock()
mCamera.release()
}
override fun surfaceCreated(p0: SurfaceHolder?) {
Log.e("MyCameraView","OPEN")
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT)
mCamera.setDisplayOrientation(90)
mCamera.setPreviewCallback(this)
mCamera.setPreviewDisplay(holder)
mCamera.setFaceDetectionListener(this)
mCamera.startPreview();
mCamera.startFaceDetection()
}
private fun getOptimalSzie(sizes: List<Camera.Size>): Camera.Size {
var pos = 0
var ratio = 0
var viewRatio = height/width
sizes.forEachIndexed { index, size ->
val curRatio = size.width/size.height
if(ratio == 0 ) ratio = curRatio
else if( (viewRatio - curRatio) < (viewRatio - ratio) ){
ratio = curRatio
pos = index
}
}
return sizes[pos]
}
override fun onPreviewFrame(data: ByteArray?, camera: Camera) {
if(allowTake) {
val parameters = camera.getParameters()
val width = parameters.previewSize.width
val height = parameters.previewSize.height
val yuv = YuvImage(data, parameters.previewFormat, width, height, null)
val out = ByteArrayOutputStream()
yuv.compressToJpeg(Rect(0, 0, width, height), 50, out)
val bytes = out.toByteArray()
val b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
detected?.invoke(bytes)
allowTake = false
hasTake = true
}
}
var hasTake = false
private var allowTake = false
override fun onFaceDetection(faces: Array<out Camera.Face>?, camera: Camera?) {
if(!hasTake) {
allowTake = true
}
}
private var detected: ((bitmap : ByteArray) -> Unit)? = null
fun onFaceDetected(detected : ( bitmap : ByteArray )->Unit){
this.detected = detected
}
}
我喜欢它!我改为使用 TextureView。它有四种回调方法。这是其中之一
onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int)
当我回到 activity 时被调用了!!! 这样我回来的时候就可以打开相机了