今天遇到一个android系统在切换横竖屏时一直卡着不动,大概3秒以后才能转过来的问题。最后定位到是由于ScreenRotationAnimation类的构造函数调用了

SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(

SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);

进行截屏导致的。

截屏函数最终是由SurfaceFlinger完成的。在surfaceflinger中加入日志调试。

nsecs_t st = systemTime();

result = flinger->captureScreenImplLocked(hw,

producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);

nsecs_t et = systemTime();

ALOGI("surfaceflinger captureScreenImplLocked use time:%dms", (int)ns2ms(et - st));

得到以下输出:

03-11 14:12:44.550 2259-2797/? W/ScreenRotationAnimation: SurfaceControl.screenshot use 3142ms

03-11 14:13:01.950 2259-2669/? W/ScreenRotationAnimation: SurfaceControl.screenshot use 3282ms

03-11 14:23:26.250 2259-2669/? W/ScreenRotationAnimation: SurfaceControl.screenshot use 3176ms

03-11 14:23:36.790 2259-2668/? W/ScreenRotationAnimation: SurfaceControl.screenshot use 3239ms

为什么需要这么长时间?

最后研究发现这个时间跟SurfaceView的数量还有关系,每多一个SurfaceView截屏时间就多个500到600毫秒,我的界面总共添加了3个SurfaceView,所以截屏时间花了3秒。

如果一个SurfaceView都不添加,截屏只需要花费大概600毫秒的时间。

看了一眼captureScreenImplLocked这个函数的实现,发现这个函数很神奇,只调用了几个GL函数,截屏就完成了。

status_t SurfaceFlinger::captureScreenImplLocked(

const sp& hw,

const sp& producer,

uint32_t reqWidth, uint32_t reqHeight,

uint32_t minLayerZ, uint32_t maxLayerZ)

{

ATRACE_CALL();

// get screen geometry

const uint32_t hw_w = hw->getWidth();

const uint32_t hw_h = hw->getHeight();

// if we have secure windows on this display, never allow the screen capture

if (hw->getSecureLayerVisible()) {

ALOGW("FB is protected: PERMISSION_DENIED");

return PERMISSION_DENIED;

}

if ((reqWidth > hw_w) || (reqHeight > hw_h)) {

ALOGE("size mismatch (%d, %d) > (%d, %d)",

reqWidth, reqHeight, hw_w, hw_h);

return BAD_VALUE;

}

reqWidth = (!reqWidth) ? hw_w : reqWidth;

reqHeight = (!reqHeight) ? hw_h : reqHeight;

// Create a surface to render into

sp surface = new Surface(producer);

ANativeWindow* const window = surface.get();

// set the buffer size to what the user requested

native_window_set_buffers_user_dimensions(window, reqWidth, reqHeight);

// and create the corresponding EGLSurface

EGLSurface eglSurface = eglCreateWindowSurface(

mEGLDisplay, mEGLConfig, window, NULL);

if (eglSurface == EGL_NO_SURFACE) {

ALOGE("captureScreenImplLocked: eglCreateWindowSurface() failed 0x%4x",

eglGetError());

return BAD_VALUE;

}

if (!eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext)) {

ALOGE("captureScreenImplLocked: eglMakeCurrent() failed 0x%4x",

eglGetError());

eglDestroySurface(mEGLDisplay, eglSurface);

return BAD_VALUE;

}

renderScreenImplLocked(hw, reqWidth, reqHeight, minLayerZ, maxLayerZ, false);

// and finishing things up...

if (eglSwapBuffers(mEGLDisplay, eglSurface) != EGL_TRUE) {

ALOGE("captureScreenImplLocked: eglSwapBuffers() failed 0x%4x",

eglGetError());

eglDestroySurface(mEGLDisplay, eglSurface);

getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);

return BAD_VALUE;

}

eglDestroySurface(mEGLDisplay, eglSurface);

getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);

return NO_ERROR;

}

不明觉厉,这个函数我是改不了了,不过还好我们这个设备是墨水屏,刷新特别慢,在旋转时不需要动画,可以想办法去掉动画,这样就不用调用截屏函数了。

首先打印一下调用堆栈,看看谁调用的截屏函数。

try {

throw new Exception();

} catch(Exception e) {

e.printStackTrace();

}

long st = System.currentTimeMillis(); SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(

SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);

long et = System.currentTimeMillis();

Slog.w(TAG, "SurfaceControl.screenshot use " + (et - st) + "ms");

得到以下输出:

03-11 14:27:39.840 2259-2439/? W/System.err: java.lang.Exception

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.wm.ScreenRotationAnimation.(ScreenRotationAnimation.java:260)

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.wm.WindowManagerService.startFreezingDisplayLocked(WindowManagerService.java:9945)

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.wm.WindowManagerService.updateRotationUncheckedLocked(WindowManagerService.java:5960)

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.wm.WindowManagerService.updateOrientationFromAppTokensLocked(WindowManagerService.java:3708)

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.wm.WindowManagerService.updateOrientationFromAppTokensLocked(WindowManagerService.java:3645)

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.wm.WindowManagerService.updateOrientationFromAppTokens(WindowManagerService.java:3633)

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.am.ActivityManagerService.setRequestedOrientation(ActivityManagerService.java:3596)

03-11 14:27:39.840 2259-2439/? W/System.err: at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:955)

03-11 14:27:39.840 2259-2439/? W/System.err: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2084)

03-11 14:27:39.840 2259-2439/? W/System.err: at android.os.Binder.execTransact(Binder.java:404)

03-11 14:27:39.850 2259-2439/? W/System.err: at dalvik.system.NativeStart.run(Native Method)

根据日志查看WindowManagerService.java 9945行附近,有如下代码:

if (CUSTOM_SCREEN_ROTATION) {

mExitAnimId = exitAnim;

mEnterAnimId = enterAnim;

final DisplayContent displayContent = getDefaultDisplayContentLocked();

final int displayId = displayContent.getDisplayId();

ScreenRotationAnimation screenRotationAnimation =

mAnimator.getScreenRotationAnimationLocked(displayId);

if (screenRotationAnimation != null) {

screenRotationAnimation.kill();

}

// TODO(multidisplay): rotation on main screen only.

screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,

mFxSession, inTransaction, mPolicy.isDefaultOrientationForced());

mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);

}

重点是if (CUSTOM_SCREEN_ROTATION) {判断条件,再搜索一下CUSTOM_SCREEN_ROTATION变量,发现只有一个初始值,中间没有任何赋值的地方。

/**

* If true, the window manager will do its own custom freezing and general

* management of the screen during rotation.

*/

static final boolean CUSTOM_SCREEN_ROTATION = true;

既然是这样,把CUSTOM_SCREEN_ROTATION 修改为false试试效果看。

哇!果然很快,就是效果有点儿差,能看得见黑屏。

标签:11,03,14,横竖,System,hw,2259,Android,卡顿

来源: https://blog.csdn.net/taohongtaohuyiwei/article/details/104797227

android 横屏切换竖屏 卡顿,Android横竖屏切换卡顿问题相关推荐

  1. android studio 全屏布局中,横竖屏使用不同布局失效问题

    最近在做一个小东西,使用的是全屏布局,但横竖屏显示布局不同,之前做的是一个横屏布局,竖屏的时候显示的乱七八糟.如图: 横屏: 竖屏: 后来重新做了一个竖屏布局,并按照网上的方法进行设置,使横竖屏加载不 ...

  2. 修正Android基于ZXing的二维码扫描——横竖屏自由切换

    概述: 此博客是基于开源的框架ZXing.ZXing用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口.ZXing可以实现使用手机的内置的摄像头完成条形码的扫描及解码.该 ...

  3. android 横竖屏切换时候activity的生命周期,横竖屏切换时候Activity的生命周期

    minifest中的设置如下:screenOrientation设置为"sensor". 本人使用的是Android7.0版本 1.新建一个Activity,并把各个生命周期打印出 ...

  4. android悬浮框横竖屏切换,Activity如何管理对话框(横竖屏切换保持对话框的最佳办法)...

    在Activity中我们要保持横竖屏切换时用户的数据一般是用onSaveinstancestate的方式,dialog也是可以的,但是有更好的方法,Activity专门对dialog提供了自己的管理机 ...

  5. Android横屏竖屏切换的问题

    转自:http://blog.sina.com.cn/s/blog_77c632410101790w.html 一.禁止横竖屏转换 Android横竖屏切换在手机开发中比较常见,很多软件在开发过程中为 ...

  6. android横屏竖屏设置

    Android横竖屏切换总结(Android资料) Android横竖屏要解决的问题应该就两个: 一.布局问题 二.重新载入问题 1.布局问题:如果不想让软件在横竖屏之间切换,最简单的办法就是在项目的 ...

  7. Android零基础入门第76节:Activity数据保存和横竖屏切换

    在前面几期学习了Activity的创建.配置.启动和停止,还学了Activity的生命周期,本期一起来学习Activity有关的更多事儿. 一.数据保存 通过上一期 LogCat 窗口打印的日志可以看 ...

  8. 解决Android手机 屏幕横竖屏切换

    Android中当屏幕横竖屏切换时,Activity的生命周期是重新加载(说明当前的Activity给销毁了,但又重新执行加载),怎么使屏幕横竖屏切换时,当前的Activity不销毁呢? 1. 在An ...

  9. 你还在问android横竖屏切换的生命周期?

    本文原创,转载请注明来自xiaoQLu http://www.cnblogs.com/xiaoQLu/p/3324503.html 开源帮助android获得了飞速的发展,开源也导致了数不清的碎片问题 ...

  10. android横竖屏切换布局闪退,Android-Activity横竖屏切换不杀死Activity 并监听横竖屏切换...

    在上一篇博客,Android-Activity临时数据的保存,中讲解到,当发生横竖屏切换的时候,系统会杀死Activity并重新启动Activity 系统会杀死Activity 12-12 08:11 ...

最新文章

  1. 鸟哥的Linux私房菜(服务器)- 簡易 APT/YUM 伺服器設定
  2. 广药谋定中国农民丰收节交易会-万祥军:谋定乡村振兴基金
  3. 银屑病与寿命的关系(调研手稿七)
  4. 2年工作经验进 初创公司_沟通是关键:通过两家初创公司获得的成长经验教训+找工作...
  5. conda安装pytorch1.10.1+paddlepaddle-gpu2.2.1+cuda10.2+cudnn7.6.5
  6. vue-ls vue 本地储存示例
  7. ERA5 积雪 降雪 区别_面对大雪吧~2020陕西首场,以下区域积雪将达20厘米
  8. springboot整合mysql5.7_详解SpringBoot整合MyBatis详细教程
  9. SPSS软件安装与常见入门问题
  10. matlab生成的图片有边,科学网—图片空白边缘处理/统计直方图---matlab/保存生成高质量的清晰图 - 杨小林的博文...
  11. 图像处理之边缘检测[微分算子、Canny算子和LOG算子]
  12. php在线拼图游戏,js+html5实现可在手机上玩的拼图游戏_javascript技巧
  13. 全球最最可爱的的10种著名小型犬
  14. android 画图
  15. 2db多少功率_功率和db换算(功率与db换算表)
  16. P2P与SIP技术的研究
  17. [香橙派]win10使用简短的cmd命令实现ssh快速登录
  18. dell服务器经常自动关机,戴尔15R电脑win10系统总是自动关机?
  19. dbca -silent静默安装12c rac数据库
  20. 联手腾讯八百客CRM实现“本土化”弯道超车

热门文章

  1. 初学者选黑卡还是微单_摄影与记录生活均适宜:三款9000元内APSC画幅微单推荐...
  2. 小米前端实习面试题和一些经验
  3. SQL 按照两个字段去除列重复的数据,保留一行。
  4. 跟社区学laravel博客实战1
  5. 高度近视、青光眼、视网膜脱落...这些人能坐飞机吗?
  6. Python——类的声明与定义
  7. php项目接入xxl-job调度系统的示例详解
  8. iPhone手机相关知识
  9. iCloud 照片windows 快速备份释放空间的方案
  10. java网络学习之 JSSE 介绍 包含sslcontext(15)