kru*_*oid 71 camera android surfaceview
我一直在尝试实现一个需要在表面上进行相机预览的应用程序.在我看到事物时,活动和表面生命周期都包含以下状态:
onResume()->onSurfaceCreated()->onSurfaceChanged()onPause()->onSurfaceDestroyed()在此方案中,我可以像打开/释放相机相应的调用和启动/停止在预览onPause/onResume和onSurfaceCreated()/onSurfaceDestroyed().
它工作正常,除非我锁定屏幕.当我启动应用程序时,然后锁定屏幕并在以后解锁它我看到:
onPause()- 屏幕锁定后没有别的 - 然后onResume()解锁后 - 之后没有表面回调.实际上,onResume()在按下电源按钮并且屏幕打开后调用,但是锁定屏幕仍然处于活动状态,因此,在活动变得均匀可见之前.
通过这种方案,我在解锁后得到一个黑屏,并且没有调用表面回调.
这是一个代码片段,不涉及相机的实际工作,而是SurfaceHolder回调.即使在我的手机上使用此代码,也会重现上述问题(按"后退"按钮时会以正常顺序调用回调,但在锁定屏幕时会丢失):
class Preview extends SurfaceView implements SurfaceHolder.Callback {
private static final String tag= "Preview";
public Preview(Context context) {
super(context);
Log.d(tag, "Preview()");
SurfaceHolder holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(tag, "surfaceCreated");
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(tag, "surfaceDestroyed");
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.d(tag, "surfaceChanged");
}
}
Run Code Online (Sandbox Code Playgroud)
关于活动暂停后表面为何仍未被破坏的任何想法?另外,在这种情况下,您如何处理相机生命周期?
emr*_*s57 58
编辑:如果targetSDK大于10,把应用睡觉通话onPause 和 onStop.资源
我在姜饼手机上的一个小型相机应用程序中查看了Activity和SurfaceView的生命周期.你是完全正确的; 按下电源按钮使手机进入睡眠状态时,表面不会被破坏.当手机进入睡眠状态时,活动会这样做onPause.(并且不这样做onStop.)它会onResume在手机唤醒时发生,并且,正如您所指出的那样,当锁定屏幕仍然可见并接受输入时,它会执行此操作,这有点奇怪.当我通过按Home键使Activity不可见时,Activity同时执行onPause和onStop.surfaceDestroyed在这种情况下,某些东西会在结束onPause和开始之间产生回调onStop.它不是很明显,但看起来确实非常一致.
当按下电源按钮使手机进入睡眠状态时,除非明确停止操作,否则相机会继续运行!如果我让相机为每个预览帧执行每个图像回调,并且其中有一个Log.d(),那么当手机假装睡觉时,日志语句会不断出现.我认为那是非常偷偷摸摸的.
作为另一混乱,回调surfaceCreated和surfaceChanged发生后 onResume在活动,如果正在产生的表面.
作为一项规则,我在实现SurfaceHolder回调的类中管理相机.
class Preview extends SurfaceView implements SurfaceHolder.Callback {
private boolean previewIsRunning;
private Camera camera;
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
// ...
// but do not start the preview here!
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// set preview size etc here ... then
myStartPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
myStopPreview();
camera.release();
camera = null;
}
// safe call to start the preview
// if this is called in onResume, the surface might not have been created yet
// so check that the camera has been set up too.
public void myStartPreview() {
if (!previewIsRunning && (camera != null)) {
camera.startPreview();
previewIsRunning = true;
}
}
// same for stopping the preview
public void myStopPreview() {
if (previewIsRunning && (camera != null)) {
camera.stopPreview();
previewIsRunning = false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在活动中:
@Override public void onResume() {
preview.myStartPreview(); // restart preview after awake from phone sleeping
super.onResume();
}
@Override public void onPause() {
preview.myStopPreview(); // stop preview in case phone is going to sleep
super.onPause();
}
Run Code Online (Sandbox Code Playgroud)
这似乎对我有用.旋转事件导致销毁和重新创建活动,这会导致SurfaceView被销毁和重新创建.
val*_*cat 21
另一种工作正常的简单解决方案 - 改变预览表面的可见性.
private SurfaceView preview;
Run Code Online (Sandbox Code Playgroud)
预览是onCreate方法中的init .在预览表面的onResume方法集中View.VISIBLE:
@Override
public void onResume() {
preview.setVisibility(View.VISIBLE);
super.onResume();
}
Run Code Online (Sandbox Code Playgroud)
并分别onPause设置可见性View.GONE:
@Override
public void onPause() {
super.onPause();
preview.setVisibility(View.GONE);
stopPreviewAndFreeCamera(); //stop and release camera
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
41662 次 |
| 最近记录: |