【问题标题】:How does Android take screenshots?Android如何截取屏幕截图?
【发布时间】:2013-12-12 07:34:31
【问题描述】:

我知道如何截取屏幕截图,但我想知道它是如何工作的。

至少从 Android 4.0 开始,您已经可以通过同时按住手机上的音量减小键和电源键来截屏,Android 会捕获当前屏幕并将其保存到 SD 卡中。

我只是想知道是否有人知道这是如何工作的,例如,它是在后台持续运行的服务,还是每个应用程序内置的东西,或者 .还有,它在Android源代码的什么位置?

谢谢!

【问题讨论】:

  • 如果你真的想了解Android,你应该尝试了解GNU/Linux。在这种情况下,有一个窗口管理器正在运行,它处理它,就像 GNU/Linux 下的 X11 一样。

标签: android screenshot


【解决方案1】:

浏览sourcecode,我找到了监听组合键并启动进程的部分:

具体代码如下:

http://androidxref.com/4.1.1/xref/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#3270

【讨论】:

    【解决方案2】:

    我刚刚在这里找到了源码树中的代码:https://github.com/android/platform_frameworks_base/tree/master/packages/SystemUI/src/com/android/systemui/screenshot

    我想这只是通读它以更好地理解该过程的问题。

    【讨论】:

    • 看不出为什么投反对票。所需的一切都在那里。 +1 恢复 Androidverse 的自然平衡。顺便说一句,你应该稍后再回来接受你自己的答案。
    • 谢谢,我也不知道为什么它被否决了……我不想接受我自己的答案,因为我认为这还不够。它只显示一些代码在源代码树中的位置,而不是它是如何工作的。
    【解决方案3】:

    如果您只想截取非常直接的屏幕截图:

    public Bitmap screenShot(View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
                view.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
        return bitmap;
    }
    

    只需使用您想要快照的视图调用此方法.. 因此,如果您想要整个屏幕,只需将最顶部的ViewGroup 传递给您。如果您想要系统控件也只需调用:

    screenShot((ViewGroup) view.getParent());
    

    现在,如果您想知道“降低音量 + 电源键”在操作系统中的工作原理,那么您也将无法访问。无法从 APK AFAIK 拦截电源按钮。

    【讨论】:

    • 谢谢,但我指的是屏幕截图的全局过程。
    【解决方案4】:

    Android 应用程序使用意图来调用系统级资源。例如——大多数运行相机的软件都是由操作系统提供的。 Android 操作系统基于 unix/linux 内核,因此使用相机看起来像这样。

    1. 应用程序/进程决定要使用相机。
    2. 该应用程序/进程构建一个意图并将其传递给操作系统。
    3. 意图由操作系统处理,相机软件在新进程中执行(exec)。调用进程可以在同步调用 Intent 时阻止它,或者它可以异步运行,调用应用程序和 Intent 调用的应用程序可以同时运行。在相机的示例中,它可能会被同步调用并阻塞。
    4. 用户使用相机进程拍照。
    5. Camera 进程退出并生成错误或图片。
    6. 操作系统执行一些ipc(进程间通信)将图片传回调用进程。根据应用程序调用的意图类型,使用管道或消息传递的选择留给操作系统。相机可能会使用消息传递,因为父进程在子进程运行时被阻塞。
    7. 现在阻塞等待返回意图的调用进程被操作系统唤醒并返回到运行状态。
    8. 图片已返回给调用应用程序,供其使用。

    当您拍摄屏幕截图时,这正是发生的情况。有一个进程正在运行来处理用户界面。它基本上坐下来等待输入和过滤任何应该由操作系统解释的内容,然后再通过管道传输到当前正在运行的应用程序。这是另一个 unix 约定,此时在我能想到的每个操作系统中都是标准的——管道输入流。它允许操作系统在传递给应用程序之前捕获更高优先级的输入,例如操作系统控制命令。 (想想 Windows 中的 ctrl-alt-delete,或 unix 中的 ctrl-c/ctrl-z。)当屏幕截图键被按下时,这个上游 io 进程执行一个特殊的程序来拍摄屏幕截图(通过意图)和命令从未真正传递给“正在运行”的应用程序。该程序在新进程中执行(exec),构建屏幕位图,将其保存到画廊空间,然后死掉——所有这些都与调度程序处理时间共享异步,因此手机始终感觉“响应”。您在 John Bokers 中看到使用所有 gorp 回答源代码来实现这一点。

    【讨论】:

    • 那么,您在相机应用程序中无法截取屏幕截图的原因是因为这将涉及异步调用您已经在其中的活动?
    • 相机和屏幕截图应用程序将从两个不同的缓冲区中读取。相机从相机缓冲区中读取,而屏幕截图程序正在从屏幕缓冲区中读取。因此,如果您也想要并完全控制源,则可以从相机中截取屏幕截图。我的猜测是你不能,因为相机在画廊文件夹中放置了一个 IO 块,因此屏幕截图程序在相机运行时无法写入它。这样做的原因是为了在照片文件夹上提供良好的同步并保持相机更稳定。
    • 但这只是猜测,我没有看过源代码或类似的东西。
    猜你喜欢
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 2017-10-09
    相关资源
    最近更新 更多