Android 后摄相机退出速度慢问题分析及优化
一、问题:
在MMITest中后主摄拍照完成点击通过或者失败,比前摄退出慢1s左右
二、问题分析
1、分析log如下:
前相机测试:S0020D3 01-02 01:13:38.000 789 5591 I ActivityTaskManager: START u0 {cmp=com.sprd.validationtools/.itemstest.camera.FrontCameraTestActivity (has extras)} with LAUNCH_MULTIPLE from uid 1000 pid 3884 (BAL_ALLOW_ALLOWLISTED_UID) result code=START_SUCCESS //点击进入前相机测试
M002276 01-02 01:13:38.357 3884 8970 I FrontCameraTestActivity: start preview //进入测试项开始预览
M002428 01-02 01:13:38.897 409 9003 I Cam3OEMIf: 4900, receivePreviewFrame: Launch Camera Time:687(ms).//打开预览耗时
M0027A9 01-02 01:13:42.718 3884 3884 D onclick : pass..com.sprd.validationtools.itemstest.camera.FrontCameraTestActivity@7e51409 //点击通过按钮
M0027AA 01-02 01:13:42.719 3884 3884 D BaseActivity: storeResult classname:com.sprd.validationtools.itemstest.camera.FrontCameraTestActivity //保存测试结果
S00298D 01-02 01:13:43.010 789 1147 I WindowManager: Input focus has changed to Window{50e05e4 u0 com.sprd.validationtools/com.sprd.validationtools.itemstest.ListItemTestActivity}, [type=1]-[Surface(name=*Title#590)/@0x7de640, shown=false, alpha=0.0, windowType=1] from c49cb57 com.sprd.validationtools/com.sprd.validationtools.itemstest.camera.FrontCameraTestActivity mDisplayId 0 updateInputWindows true//返回到测试列表界面
后相机测试:
S002AE1 01-02 01:13:44.510 789 3333 I ActivityTaskManager: START u0 {cmp=com.sprd.validationtools/.itemstest.camera.CameraTestActivity (has extras)} with LAUNCH_MULTIPLE from uid 1000 pid 3884 (BAL_ALLOW_ALLOWLISTED_UID) result code=START_SUCCESS //点击进入前相机测试
M002CC4 01-02 01:13:44.906 3884 3884 E CameraTestActivity: start preview //进入测试项开始预览
M002EA3 01-02 01:13:45.607 409 9080 I Cam3OEMIf: 4900, receivePreviewFrame: Launch Camera Time:933(ms).//打开预览耗时 测试10次,平均700ms
M003550 01-02 01:13:54.163 3884 3884 D onclick : pass..com.sprd.validationtools.itemstest.camera.CameraTestActivity@7076185 //点击通过按钮
M003551 01-02 01:13:54.163 3884 3884 D BaseActivity: storeResult classname:com.sprd.validationtools.itemstest.camera.CameraTestActivity//保存测试结果
S003652 01-02 01:13:54.712 789 813 W ActivityTaskManager: Activity pause timeout for ActivityRecord{1b0e20f u0 com.sprd.validationtools/.itemstest.camera.CameraTestActivity t12 d0 f}}
S003811 01-02 01:13:55.531 789 803 I WindowManager: Input focus has changed to Window{50e05e4 u0 com.sprd.validationtools/com.sprd.validationtools.itemstest.ListItemTestActivity}, [type=1]-[Surface(name=*Title#620)/@0x7fb3194, shown=false, alpha=0.0, windowType=1] from 63b0934 com.sprd.validationtools/com.sprd.validationtools.itemstest.camera.CameraTestActivity mDisplayId 0 updateInputWindows true//返回到测试列表界面
2、在log中发现异常:Activity pause timeout for ActivityRecord{1b0e20f u0 com.sprd.validationtools/.itemstest.camera.CameraTestActivity t12 d0 f}},protected void onPause()后退出速度在300ms左右
3、问题定位:
@Override
protected void onPause() { ... ...}此方法执行出现问题
4、查看代码中的protected void onPause()方法,在 onPause()中有执行相机闪光灯模式关闭的操作。涉及到Camera对象的参数设置,可能需要一定的处理时间,尤其是在某些设备上可能较慢,如果放在onPause()里,这时候Activity可能还在进行其他暂停相关的操作,如果Camera操作耗时,会导致主线程被阻塞,从而延迟onPause()的完成,进而影响Activity切换的流畅度。onPause()是在Activity失去焦点但仍部分可见的时候调用,比如另一个Activity以对话框形式出现,所以,onPause()执行的时间点比较早,可能在界面还在部分显示的时候,这时候如果进行一些资源释放的操作,可能会阻塞主线程,导致界面卡顿,用户觉得退出慢
5、优化方案:onPause()是在Activity失去焦点但仍部分可见的时候调用,而onStop()是在Activity完全不可见时调用,比如用户跳转到其他Activity或者回到主屏幕,这时候用户已经看不到界面了,所以即使这里的代码执行时间较长,对用户感知的影响较小,可能不会明显感觉到退出变慢。因此,将耗时的操作比如关闭闪光灯模式操作移到onStop()中可以改善用户体验。
...
@Override protectedvoid onStop() { super.onStop(); if (mCamera != null) { Camera.Parameters parameters = mCamera.getParameters(); parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); mCamera.setParameters(parameters); } }
三、总结
将相机操作从 onPause()
移至 onStop()
,利用了生命周期阶段的特性:将耗时操作推迟到界面不可见时执行,避免阻塞主线程,从而提升用户体验