参考资料:
DJLZPP
AndroidQ 图形系统(11)UI刷新,SurfaceFlinger,Vsync机制总结_DJLZPP的博客-优快云博客
在以前的学习中,通过GraphicBuffer的传送和数据读写了解到数据的传送显示流程,没有涉及到画面的刷新,这里通过view的刷新来学习一下,
在GLSurfaceView中,相关onDrawFrame方法会随着屏幕刷新而调用起来。
在普通的view里面,通过调用invalidate方法来注册vsync信号,开始一帧画面的绘制,调用到onDraw方法。invalidate这个方法名字很奇怪,如果是pre-draw似乎好理解一些,也许是想表达当前画面失效的意思吧,invalidate是个理解的关键点,如同GraphicBuffer一样
DJLZPP同学的这个图很好,(借用一下,原文链接在上面)
没有做过app的可能对invalidate并不熟悉,PointerLocationView中绘制touch轨迹的时候,就使用了invalidate来进行刷新,手指滑动的时候调用,来刷新画面
527 public void onPointerEvent(MotionEvent event) {
528 final int action = event.getAction();
529 int NP = mPointers.size();
530
531 if (action == MotionEvent.ACTION_DOWN
532 || (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
533 final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
534 >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for down
535 if (action == MotionEvent.ACTION_DOWN) {
536 for (int p=0; p<NP; p++) {
537 final PointerState ps = mPointers.get(p);
538 ps.clearTrace();
539 ps.mCurDown = false;
540 }
541 mCurDown = true;
542 mCurNumPointers = 0;
543 mMaxNumPointers = 0;
544 mVelocity.clear();
545 if (mAltVelocity != null) {
546 mAltVelocity.clear();
547 }
548 }
549
550 mCurNumPointers += 1;
551 if (mMaxNumPointers < mCurNumPointers) {
552 mMaxNumPointers = mCurNumPointers;
553 }
554
555 final int id = event.getPointerId(index);
556 while (NP <= id) {
557 PointerState ps = new PointerState();
558 mPointers.add(ps);
559 NP++;
560 }
561
562 if (mActivePointerId < 0 ||
563 !mPointers.get(mActivePointerId).mCurDown) {
564 mActivePointerId = id;
565 }
566
567 final PointerState ps = mPointers.get(id);
568 ps.mCurDown = true;
569 InputDevice device = InputDevice.getDevice(event.getDeviceId());
570 ps.mHasBoundingBox = device != null &&
571 device.getMotionRange(MotionEvent.AXIS_GENERIC_1) != null;
572 }
573
574 final int NI = event.getPointerCount();
575
576 mVelocity.addMovement(event);
577 mVelocity.computeCurrentVelocity(1);
578 if (mAltVelocity != null) {
579 mAltVelocity.addMovement(event);
580 mAltVelocity.computeCurrentVelocity(1);
581 }
582
583 final int N = event.getHistorySize();
584 for (int historyPos = 0; historyPos < N; historyPos++) {
585 for (int i = 0; i < NI; i++) {
586 final int id = event.getPointerId(i);
587 final PointerState ps = mCurDown ? mPointers.get(id) : null;
588 final PointerCoords coords = ps != null ? ps.mCoords : mTempCoords;
589 event.getHistoricalPointerCoords(i, historyPos, coords);
590 if (mPrintCoords) {
591 logCoords("Pointer", action, i, coords, id, event);
592 }
593 if (ps != null) {
594 ps.addTrace(coords.x, coords.y, false);
595 }
596 }
597 }
598 for (int i = 0; i < NI; i++) {
599 final int id = event.getPointerId(i);
600 final PointerState ps = mCurDown ? mPointers.get(id) : null;
601 final PointerCoords coords = ps != null ? ps.mCoords : mTempCoords;
602 event.getPointerCoords(i, coords);
603 if (mPrintCoords) {
604 logCoords("Pointer", action, i, coords, id, event);
605 }
606 if (ps != null) {
607 ps.addTrace(coords.x, coords.y, true);
608 ps.mXVelocity = mVelocity.getXVelocity(id);
609 ps.mYVelocity = mVelocity.getYVelocity(id);
610 mVelocity.getEstimator(id, ps.mEstimator);
611 if (mAltVelocity != null) {
612 ps.mAltXVelocity = mAltVelocity.getXVelocity(id);
613 ps.mAltYVelocity = mAltVelocity.getYVelocity(id);
614 mAltVelocity.getEstimator(id, ps.mAltEstimator);
615 }
616 ps.mToolType = event.getToolType(i);
617
618 if (ps.mHasBoundingBox) {
619 ps.mBoundingLeft = event.getAxisValue(MotionEvent.AXIS_GENERIC_1, i);
620 ps.mBoundingTop = event.getAxisValue(MotionEvent.AXIS_GENERIC_2, i);
621 ps.mBoundingRight = event.getAxisValue(MotionEvent.AXIS_GENERIC_3, i);
622 ps.mBoundingBottom = event.getAxisValue(MotionEvent.AXIS_GENERIC_4, i);
623 }
624 }
625 }
626
627 if (action == MotionEvent.ACTION_UP
628 || action == MotionEvent.ACTION_CANCEL
629 || (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
630 final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
631 >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for UP
632
633 final int id = event.getPointerId(index);
634 if (id >= NP) {
635 Slog.wtf(TAG, "Got pointer ID out of bounds: id=" + id + " arraysize="
636 + NP + " pointerindex=" + index
637 + " action=0x" + Integer.toHexString(action));
638 return;
639 }
640 final PointerState ps = mPointers.get(id);
641 ps.mCurDown = false;
642
643 if (action == MotionEvent.ACTION_UP
644 || action == MotionEvent.ACTION_CANCEL) {
645 mCurDown = false;
646 mCurNumPointers = 0;
647 } else {
648 mCurNumPointers -= 1;
649 if (mActivePointerId == id) {
650 mActivePointerId = event.getPointerId(index == 0 ? 1 : 0);
651 }
652 ps.addTrace(Float.NaN, Float.NaN, false);
653 }
654 }
655
656 invalidate();
657 }
658