问题出现场景
发现从唤醒页面(Activity-A:此页面存在surfaceView,来展示摄像头的镜像),跳转到主页面(Activity-B)的过程中会出现ANR异常。
问题定位:
1,log中检索ANR,定位到位置。Reason: Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 2. Wait queue head age: 5584.1ms.
2,下面进这种Wrote stack traces to ‘/data/anr/traces.txt’
3,我们在手机存储空间上找到这个文件————traces.txt
4,因为是ANR现象,所以我们关注main线程。在traces.txt中检索“main”。发现如下的log输出:
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:840)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:873)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
at android.view.SurfaceView.updateWindow(SurfaceView.java:528)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:247)
at android.view.View.dispatchWindowVisibilityChanged(View.java:10357)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
复现步骤
总结本次ANR过程:
第一步:执行了mHolder.lockCanvas(),lock成功获得锁
第二步:此时恰巧遇到SurfaceView销毁,surfaceDestroyed执行,并且将mNativeObject置为0
第三步:调用unlockCanvasAndPost,但是由于mNativeObject为0,所以抛出异常,并没有成功unlock
第四步:SurfaceView重新创建,尝试lock,因为上次的锁没有释放,所以进入了无限等待。
解决方法
我们只需要在surfaceview销毁之前进行,使得surfaceview变为不可见即可(在activity的生命周期onPause()中设置)。
surfaceview.setVisibility(View.GONE);