SurfaceHolder 回调与 Activity 生命周期有何关系?

2023-12-23

我一直在尝试实现一个需要在表面上进行相机预览的应用程序。 据我所知,活动和表面生命周期都包含以下状态:

  1. 当我第一次启动我的活动时:onResume()->onSurfaceCreated()->onSurfaceChanged()
  2. 当我离开我的活动时:onPause()->onSurfaceDestroyed()

在这个方案中,我可以执行相应的调用,例如打开/释放相机和开始/停止预览onPause/onResume and 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");
    }
}

关于为什么活动暂停后表面仍未被破坏的任何想法?另外,在这种情况下,您如何处理相机的生命周期?


Edit:如果 targetSDK 大于 10,则使应用程序进入睡眠状态调用onPause and onStop. Source https://stackoverflow.com/a/25497907/1094605

我在姜饼手机上的微型相机应用程序中查看了 Activity 和 SurfaceView 的生命周期。你是完全正确的;当按下电源按钮使手机进入睡眠状态时,表面不会被破坏。当手机进入睡眠状态时,该 Activity 会执行以下操作:onPause。 (并且不做onStop.) 确实如此onResume当手机唤醒时,正如您所指出的,它会在锁定屏幕仍然可见并接受输入的情况下执行此操作,这有点奇怪。当我通过按主页按钮使活动不可见时,活动会同时执行以下操作onPause and onStop。有些事情会导致回调surfaceDestroyed在这种情况下结束之间onPause和开始onStop。虽然不是很明显,但看起来确实很一致。

当按下电源按钮使手机进入睡眠状态时,除非明确执行某些操作来停止它,否则相机会继续运行!如果我让相机为每个预览帧执行每个图像的回调,其中包含 Log.d(),则当手机假装睡眠时,日志语句会不断出现。我认为那是非常鬼祟.

另一个令人困惑的是,回调surfaceCreated and surfaceChanged happen after 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();
}

这对我来说似乎没问题。旋转事件会导致 Activity 被销毁并重新创建,这也会导致 SurfaceView 被销毁并重新创建。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SurfaceHolder 回调与 Activity 生命周期有何关系? 的相关文章

  • Web Speech API 无法在 Android 版 Chrome 中正确加载语音

    我有一个简单的应用程序 应该读出以所选语言输入到输入字段中的文本 https speech synthesis demo glitch me https speech synthesis demo glitch me 这似乎在多个浏览器的桌
  • 切换大小写错误。用于 Mac 上 Android 开发的 Eclipse IDE:将工作区合规性更改为 JRE 1.7

    当尝试在 android 项目中使用带有 switch string 的 Switch Case 时 我在 eclipse IDE 中收到错误消息 将工作区合规性更改为 JRE1 7 对于低于 1 7 的源级别 无法打开字符串类型的值 仅允
  • Android Studio 3.1.3不显示布局设计预览

    自从我上次在 android studio 中创建一个新项目以来已经有一段时间了 今天当我这样做时 android studio 没有从布局预览中显示任何内容 它是一个空白窗口 并显示 没有可显示的内容 我已经尝试过了 更新了sdks工具
  • Android 中的计时器任务在无限期时间后停止运行

    我是安卓新手 我正在开发一个应用程序 其中一段特定的代码在后台每 5 秒后执行一次 为了实现这一目标 我使用带有定时器的服务 其中包含定时器任务 有时它工作正常 但经过一段时间后 我的服务正在运行 但计时器任务在 android 中自动停止
  • 有人知道如何在android中实现像Unfold(这是iphone中的应用程序)这样的效果吗?

    我怎样才能实现这个效果呢 任何建议都会对我有帮助 None
  • Google 分析“获取配置文件”不允许我选择我的帐户

    我已经根据最新的 v4 文档完成了一个有效的谷歌分析集成 我们需要去哪里获取配置文件 from 但面临以下问题 我的谷歌分析帐户上的两个不同的应用程序有两个不同的跟踪ID 对于第一个应用程序 我得到了谷歌服务 json我将文件放置在根目录中
  • 尽管使用了 NTP 偏移量,设备仍会在几秒后启动指令

    背景 我有两台物理设备 一台 Galaxy S3 手机 和一台 Asus 700T 平板电脑 我想在同一时间执行同一组指令 因此 我使用的是 Android 的平台框架 基本 SNTP 客户端代码 https github com andr
  • 如何刷新 Android 上的 MediaStore?

    这最初是 Android 论坛上的一个一般用户问题 然而 它必然成为一个编程问题 这是我的问题 Android 有一个服务 MediaScanner 每当 我相信 SD 卡卸载和重新安装时它都会在后台运行 该服务收集卡上所有媒体文件的数据
  • Windows 7 64位android AVD启动错误:无法分配内存:8

    我刚刚更新到 Android SDK Tools r20 并尝试在 android 4 1 和 WXGA 上创建 avd 但是当我启动 AVD 时收到错误消息 配置 ini hw mainKeys no hw lcd density 320
  • ListView 可以存储多少个项目?

    我是 Android 编程新手 我想知道ListView可以存储多少个项目 我在文档中搜索 但他们没有谈论这个 如果我将很多 可能是 10k 项放入 ListAdapter 中 会影响性能吗 干杯 MK ListView 在 Android
  • 单元测试定位服务

    我有一个位置跟踪服务 正在尝试对其进行单元测试 我正在尝试使用 locationManager addTestProvider 和 setTestProviderLocation 方法来实现此目的 但是 我似乎无法通过提供程序获取任何位置并
  • 从图库加载图像时应用程序崩溃

    在我的应用程序中 我有两个按钮 一个用于从图库 从设备 加载图像 另一个用于通过访问设备的相机拍照 我的代码在某些设备上正常工作 bt在某些设备上 应用程序单击图库中的图像时崩溃 任何人都可以帮助我找出实际问题吗 public class
  • GPSTracker 类不工作

    我尝试在我的应用程序中使用我在网上找到的 GPSTracker 类 并且我之前让它工作过 但现在似乎莫名其妙地不起作用 public class GPSTracker extends Service implements LocationL
  • Motorola Android 2.2 相机忽略 EXTRA_OUTPUT 参数

    我以编程方式打开相机来拍摄视频 我告诉相机使用如下代码将视频文件放置到指定位置 Intent intent new Intent MediaStore ACTION VIDEO CAPTURE File out new File sdcar
  • 删除 android ListView 的底部分隔线

    我有固定的高度ListView 它在列表项之间有分隔线 但它还在最后一个列表项之后显示分隔线 有没有办法在最后一项之后不显示分隔线ListView 只需添加android footerDividersEnabled false 到您的 Li
  • 将 jstring 转换为 QString

    我正在调用一个返回字符串的 Java 函数 QAndroidJniObject obj QAndroidJniObject callStaticObjectMethod
  • android 以编程方式在单选组按钮之间添加填充

    我有一个 xml 格式的单选组 按钮是通过编程生成的 如何以编程方式添加按钮之间的间距 我以为是这样的LayoutParams但我的对象没有明显的setPadding or setMargins方法 这就是我正在尝试的 RadioButto
  • 如何使用 Android 手机通话时播放声音?

    是否可以通过编程方式与电话进行交互 例如 您可以通过程序向呼叫者播放音频吗 Google 尚未公开任何允许我们向特定正在进行的调用提供数据的 API 不过 您可以控制通话 检查这篇文章 here http prasanta paul blo
  • MediaRecorder 纵向模式下的视频捕获

    我正在尝试制作自定义视频应用程序 Iwork 使用清单中的设置仅 2 2 API 8 一切顺利 但我不明白为什么纵向模式视频与横向模式视频没有区别 为了检测设备改变的方向 我在 surfaceChanged 中使用此代码 if mCamer
  • SDK管理器不显示示例包选项

    我关注的是安卓安装示例的开发人员链接 http developer android com tools samples index html包裹 但是 当我展开Android平台的包列表时 没有 SDK示例 选项 复选框 可用 为什么 我已

随机推荐