当前位置: 首页 > 知识库问答 >
问题:

SurfaceHolder回调如何与活动生命周期相关?

孙鑫鹏
2023-03-14
  1. 第一次启动活动时:OnResume()->OnSurfaceCreated()->OnSurfaceChanged()
  2. 离开活动时:OnPause()->OnSurfaceDestroed()

在该方案中,我可以在onpause/onresumeonsurfaceCreated()/onsurfaceDestroed()中进行相应的调用,如打开/释放camera和启动/停止预览。

它很好用,除非我锁上屏幕。当我启动应用程序,然后锁定屏幕,然后解锁它,我看到:

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

共有1个答案

寇丰
2023-03-14

编辑:如果targetSDK大于10,则将应用程序置于Hibernate状态将调用onpauseonstop。来源

我在gingerbread手机上的一个微型相机应用程序中查看了活动和SurfaceView的生命周期。你完全正确;当按下电源键使手机进入Hibernate状态时,表面不会被破坏。当电话进入Hibernate状态时,活动执行onpause。(并且不执行onstop。)当电话唤醒时,它会执行onresume,正如您所指出的,它在锁定屏幕仍然可见并接受输入时执行此操作,这有点奇怪。当我通过按Home按钮使活动不可见时,活动同时执行onpauseonstop。在本例中,在onpause的结尾和onstop的开头之间,有一些东西会导致对surfacedestroeding的回调。不是很明显,但确实看起来很一致。

当按下电源按钮使手机Hibernate时,除非明确地做了什么来阻止它,否则相机一直在运行!如果我让相机对每个预览帧进行每幅图像的回调,其中有一个log.d(),log语句会在手机假装Hibernate的时候不断出现。我觉得这很狡猾。

另一个困惑是,如果正在创建表面,则对SurfaceCreatedSurfaceChanged的回调发生在活动中的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;
       }
   }
}

然后在活动中:

@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();
}
 类似资料:
  • Cocos Creator 为组件脚本提供了生命周期的回调函数。用户只要定义特定的回调函数,Creator 就会在特定的时期自动执行相关脚本,用户不需要手工调用它们。 目前提供给用户的生命周期回调函数主要有: onLoad start update lateUpdate onDestroy onEnable onDisable onLoad 组件脚本的初始化阶段,我们提供了 onLoad 回调函数

  • # 生命周期回调 Cocos Creator 3D为组件脚本提供了生命周期的回调函数。用户只要定义特定的回调函数,Creator 3D就会在特定的时期自动执行相关脚本,用户不需要手工调用它们。 目前提供给用户的生命周期回调函数主要有: onLoad start update lateUpdate onDestroy onEnable onDisable onLoad 组件脚本的初始化阶段,我们提

  • 我为测试函数做了简单的应用程序,如onCreate()、onStart等。每个函数都让你有自己的日志。开始测试。 null 为什么在执行应用程序时调用onResume方法?(在a中) 为什么onPause和onStop方法一起调用?(在b中) 为什么在C中调用三个方法而不是onRestart或onrestume?(c) 为什么调用onDestroy方法?(d) 附言:对不起,英语:)

  • 本文向大家介绍Android活动生命周期介绍,包括了Android活动生命周期介绍的使用技巧和注意事项,需要的朋友参考一下 示例 假定具有MainActivity的应用程序可以通过单击按钮来调用Next Activity。 和 在首次创建应用程序 d / MainActivity:从主叫MainActivity的onCreate d / MainActivity:从主叫MainActivity调用

  • 我在开始新活动时遇到了一些问题。在我的应用程序中,我设置了侦听意图的广播接收器(屏幕关闭)。当屏幕关闭时,我的应用程序应该开始新活动(当然在某些情况下。我没有制作垃圾邮件应用程序)。但有时不是。 我在清单中声明了活动“singleTop”,所以我也重写了“onNewIntent”方法。(我认为这很重要)但事情是这样的。 当手机进入睡眠状态并且满足某些条件时,屏幕上会出现两个图标(“我的活动”)。我

  • TestInstancePostProcessor defines the API for Extensions that wish to post process test instances. Common use cases include injecting dependencies into the test instance, invoking custom initializatio