最近遇到一个bug,现象为SurfaceView的Layer没有销毁,导致屏幕上一直显示该Layer。觉得该案例有点意思,故在此记录下分析过程及解决方法,供有一定framework基础的Rom开发人员参考。
现象
开心消消乐的界面一直在屏幕上显示,无论如何都不能销毁。
分析过程
首先最直接相关的模块是SurfaceFlinger,既然能看到,应该存在该Layer并且进行了合成,否则这里就有问题,用如下命令dump状态信息:
adb shell dumpsys SurfaceFlinger
这里只摘取该Layer相关的部分:
+ Layer 0x71b57b0400 (SurfaceView - com.happyelements.AndroidAnimal/com.happyelements.hellolua.MainActivity)
Region transparentRegion (this=0x71b57b0708, count=1)
[ 0, 0, 0, 0]
Region visibleRegion (this=0x71b57b0410, count=1)
[ 0, 0, 1080, 1920]
Region surfaceDamageRegion (this=0x71b57b0488, count=1)
[ 0, 0, 0, 0]
layerStack= 0, z= 21015, pos=(0,0), size=(1080,1920), crop=( 0, 0,1080,1920), finalCrop=( 0, 0, -1, -1), isOpaque=1, invalidate=0, alpha=0xff, flags=0x00000002, tr=[1.00, 0.00][0.00, 1.00]
FilterRender Layer= 0, FilterMode= 0 availableRect =( 0, 0, 0, 0)
client=0x71b86f0f40
format= 4, activeBuffer=[1080x1920:1088, 1], queued-frames=0, mRefreshPending=0
mSecure=0, mProtectedByApp=0, mFiltering=0, mNeedsFiltering=0
mTexName=54 mCurrentTexture=-1
mCurrentCrop=[0,0,0,0] mCurrentTransform=0
mAbandoned=0
-BufferQueue mMaxAcquiredBufferCount=1, mMaxDequeuedBufferCount=3, mDequeueBufferCannotBlock=0 mAsyncMode=0, default-size=[1080x1920], default-format=4, transform-hint=00, FIFO(0)={}
this=0x71b55e3000 (mConsumerName=SurfaceView - com.happyelements.AndroidAnimal/com.happyelements.hellolua.MainActivity, mConnectedApi=0, mConsumerUsageBits=0x900, mId=39, mPid=15358, producer=[-1:com.happyelements.AndroidAnimal], consumer=[15358:/system/bin/surfaceflinger])
[00:0x0] state=FREE
[01:0x0] state=FREE
[02:0x0] state=FREE
[03:0x0] state=FREE
*BufferQueueDump mIsBackupBufInited=0, mAcquiredBufs(size=0), mMode=TRACK_CONSUMER
[-1] mLastAcquiredBuf->mGraphicBuffer->handle=0x71b7636900
得到如下信息:
- flags=0x00000002,即该Layer是show和opaque状态
- alpha=0xff,即alpha值为完全不透明
- visibleRegion为[ 0, 0, 1080, 1920],说明有可见区域,而且是全屏
综合以上以及dump出来的合成信息,说明SurfaceFlinger这边的状态没有问题,符合我们看到的现象。
同时注意到有些奇怪的信息,之所以说奇怪是因为跟正常参与合成的Layer不一样:
- GraphicBuffer全部是FREE状态,正常应该至少有一个是ACQUIRED
- mCurrentTexture=-1,正常应该是>=0
- mConnectedApi=0,正常应该是>0
当然能进入到现在这种bug状态本身就不能太按常理来看待,SurfaceFlinger这边暂且先到这里。
目光转向WMS这边,用如下命令dump状态信息:
adb shell dumpsys window
唯一跟该SurfaceView相关的信息如下: