JVM/Android View知识点

JVM部分基础回忆

  • jdk8取消了永久代,jdk7常量池移到堆中
  • 新生代中Eden和Survivor内存比为8:1:1,每次只有一个survivor可以用,实际可用为90% 。新时代:老年代为1:2。
  • 大对象直接进入老年代,小对象优先进入Eden,GC发生时没有被回收,则进入survivor,熬过一定次数进入老年代,当然也并非绝对。survivor内存不足时会进入老年代,老年代不足会进行GC
  • JVM对象存活判断采用可达性分析法,GCRoot通常为永久代的对象,对象不可达时不会立刻被杀死,finalize()有机会使对象“复活”,但是此方法最好不要用。
  • 垃圾回收器基本都基于标记-清除、标记-整理和复制算法。GC发生时,用户线程停止,client模式垃圾收集器为serial和serial old(串行),server模式为PS scanvage(并发)和serial od。AndroidStudio本身的收集器默认使用CMS(并发,用户线程不会停止缩短,基于复制和标记-清除算法),Eclipse本身的收集器默认使用G1(目前最先进的收集器,使用标记-整理和复制算法,stop the world时间进一步缩短)

View/ViewGroup部分疑惑解决记录

  • VelocietyTracker滑动速度追踪
  • TouchSlop最小滑动距离(与设备有关
  • GestureDetector(这个不用多说
  • 自定义View时padding无效
  • 事件分发一旦DOWN没有被消费,后续事件不会下发,直接回调Activity.OnTounchEvent。一旦有事件被拦截,后续事件直接调用onTouchEven,不再调用onInteceptTouchEcent。除了DOWN,其他事件一旦没有被消费,直接回调Activity.onTouchEvent。

正题

关于measure(),onMeasure()和getWithMeasureDimenson,getWith()等的关系。经查看源码,实际上父ViewGroup调用onMeasure里面调用measureChild(WithMargins),再调用到getChildMeasureSpec(p1,p2,p3),p1为父View MeasureSpec,p2为padding(+margin+usedSpace),p3为layoutparameter.with,之后进一步调用子view measure(spec,spec)再调用onMeasure(spec,spec),onMeasure setMeasureDismenson并不包括margin信息!如果ViewGroup要支持margin,必须定义一个extends的MarginLayparameter,并使用measureChildWithMargin(),才可以正确获取到padding之外的margin信息。Layout()完成View布局,onLayout()完成子View布局。Draw()先绘制背景,在调用onDraw()绘制自己,最后绘制子View(dispaDraw())。

     protected void measureChild(View child, int parentWidthMeasureSpec,
            int parentHeightMeasureSpec) {
        final LayoutParams lp = child.getLayoutParams();

        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                mPaddingLeft + mPaddingRight, lp.width);
        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
                mPaddingTop + mPaddingBottom, lp.height);

        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    }

    这里的withUsed和heightUsed实在不是很懂

    protected void measureChildWithMargins(View child,
            int parentWidthMeasureSpec, int widthUsed,
            int parentHeightMeasureSpec, int heightUsed) {
        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
                        + widthUsed, lp.width);
        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
                mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
                        + heightUsed, lp.height);

        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    }





    /**
     * Does the hard part of measureChildren: figuring out the MeasureSpec to
     * pass to a particular child. This method figures out the right MeasureSpec
     * for one dimension (height or width) of one child view.
     *
     * The goal is to combine information from our MeasureSpec with the
     * LayoutParams of the child to get the best possible results. For example,
     * if the this view knows its size (because its MeasureSpec has a mode of
     * EXACTLY), and the child has indicated in its LayoutParams that it wants
     * to be the same size as the parent, the parent should ask the child to
     * layout given an exact size.
     *
     * @param spec The requirements for this view
     * @param padding The padding of this view for the current dimension and
     *        margins, if applicable
     * @param childDimension How big the child wants to be in the current
     *        dimension
     * @return a MeasureSpec integer for the child
     * 可以看出这个方法判断ViewGroup除了padding,子View的    
     * margin,还有多少空间给子View内容(包括ziView的padding)
     */
    public static int getChildMeasureSpec(int spec, int padding, int childDimension) {
        int specMode = MeasureSpec.getMode(spec);
        int specSize = MeasureSpec.getSize(spec);

        int size = Math.max(0, specSize - padding);

        int resultSize = 0;
        int resultMode = 0;

        switch (specMode) {
        // Parent has imposed an exact size on us
        case MeasureSpec.EXACTLY:
            if (childDimension >= 0) {
                resultSize = childDimension;
                resultMode = MeasureSpec.EXACTLY;
            } else if (childDimension == LayoutParams.MATCH_PARENT) {
                // Child wants to be our size. So be it.
                resultSize = size;
                resultMode = MeasureSpec.EXACTLY;
            } else if (childDimension == LayoutParams.WRAP_CONTENT) {
                // Child wants to determine its own size. It can't be
                // bigger than us.
                resultSize = size;
                resultMode = MeasureSpec.AT_MOST;
            }
            break;

        // Parent has imposed a maximum size on us
        case MeasureSpec.AT_MOST:
            if (childDimension >= 0) {
                // Child wants a specific size... so be it
                resultSize = childDimension;
                resultMode = MeasureSpec.EXACTLY;
            } else if (childDimension == LayoutParams.MATCH_PARENT) {
                // Child wants to be our size, but our size is not fixed.
                // Constrain child to not be bigger than us.
                resultSize = size;
                resultMode = MeasureSpec.AT_MOST;
            } else if (childDimension == LayoutParams.WRAP_CONTENT) {
                // Child wants to determine its own size. It can't be
                // bigger than us.
                resultSize = size;
                resultMode = MeasureSpec.AT_MOST;
            }
            break;

        // Parent asked to see how big we want to be
        case MeasureSpec.UNSPECIFIED:
            if (childDimension >= 0) {
                // Child wants a specific size... let him have it
                resultSize = childDimension;
                resultMode = MeasureSpec.EXACTLY;
            } else if (childDimension == LayoutParams.MATCH_PARENT) {
                // Child wants to be our size... find out how big it should
                // be
                resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
                resultMode = MeasureSpec.UNSPECIFIED;
            } else if (childDimension == LayoutParams.WRAP_CONTENT) {
                // Child wants to determine its own size.... find out how
                // big it should be
                resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
                resultMode = MeasureSpec.UNSPECIFIED;
            }
            break;
        }
        //noinspection ResourceType
        return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
    }

猜你喜欢

转载自blog.csdn.net/sinat_33878878/article/details/79340676
今日推荐