Android4.1和Android4.0相比,中间层转发Input消息的流程有了较大的变化。
Android4.0采用共享内存的方法将Input消息由系统进程向应用进程发送,应用进程接收到Input消息后按照FIFO的方式,顺序的将Input消息向上分发。
Android4.1采用非阻塞的套接字方式,将Input消息由系统进程向应用进程发送,应用进程在接收到Input消息后进行了批处理。应用进程收到若干个点后,会依次存入缓冲区里面,等待一个合适的时候,再按批次将这些点封装成一个MotionEvent,并将封装过的点从缓冲区里面清掉。封装后如果缓冲区里面还有剩余点,会在本批次和下一批次之间插入一个估算的点;如果缓冲区里面暂时没有剩余点,但本批次的点数在2个以上,则在本批次的最后2个点之间插入一个估算点。插点完成以后,上传给ViewRoot,这样应用层在调用相关接口获取点数时就会多一个点。
插点算法是Android4.1针对划线的优化处理,只要开启了插点的功能,不论报点率高低都会发生插点。那么,为什么在报点率高的时候没有出现划线曲折,而报点率低的时候出现了划线曲折呢?原因在于差点的预估算法和两点之间的时间间隔差有关系。
请看下面分析:
插点算法的相关公式
delta因子
delta = future.eventTime -current->eventTime
其中,future为下一批次的第一个点,current为当前批次的最后一个点
或者,future为当前批次的最后一个点,current为当前批次的倒数第二个点
alpha因子
alpha =float(current->eventTime - sampleTime) / delta
其中,sampleTime = frameTime -RESAMPLE_LATENCY
frameTime为下一帧刷图的时间, RESAMPLE_LATENCY为预估的从收到点到刷下一
帧图像时的延时大小,因此sampleTime为该批次收到最后一个点的时间。
插点计算公式
value.x =current.x + alpha * (furrent.x -current.x)
value.y =current.y + alpha * (furrent.y -current.y)
从上面的alpha因子可知,future.eventTime - current->eventTime会影响插点算法的结果,即两个点之间的时间间隔影响插点算法的准确性。而两个点之间的时间间隔和报点率相关,因此报点率的高低会影响插点算法的准确性。
从调试的结果来看,报点率越高划线越圆滑,当报点率低于90Hz时,会出现划线曲折、不圆滑的现象。