android view的生命周期

来源:互联网 发布:程序员联合网开发区 编辑:程序博客网 时间:2024/05/24 00:17

我们知道,在android创建一个view有两种方式:
1. 在xml布局文件中配置,用LayoutInflater解析加载;
这两种的生命周期略有不同;
2. 直接在代码中new 出来;

首先看一下用LayoutInflater解析的方式,分3种情况:

  1. android:visibility=”visible”(默认值)

    解析加载过程

    D/ViewLifeTime: ViewLifeTime: [context, attrs]D/ViewLifeTime: onFinishInflate: D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView@5343b370], visibility = [4]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView@5343b370], visibility = [0]D/ViewLifeTime: onAttachedToWindow: D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onMeasure() called with: widthMeasureSpec = [1073742592], heightMeasureSpec = [1073742968]D/ViewLifeTime: onSizeChanged() called with: w = [768], h = [1144], oldw = [0], oldh = [0]D/ViewLifeTime: onLayout() called with: changed = [true], left = [0], top = [88], right = [768], bottom = [1232]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]D/ViewLifeTime: onMeasure() called with: widthMeasureSpec = [1073742592], heightMeasureSpec = [1073742968]D/ViewLifeTime: onLayout() called with: changed = [false], left = [0], top = [88], right = [768], bottom = [1232]D/ViewLifeTime: onDraw() called with: canvas = [android.view.GLES20RecordingCanvas@53450f58]

    按Home键进入后台

    D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView@5343b370], visibility = [4]

    重新回到应用内

    D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView@5343b370], visibility = [0]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]

    按back键

    D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onDetachedFromWindow: 
  2. invisible
    解析加载过程

    D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.alex.ui.ViewLifeTime{42d34410 I.ED.... ........ 0,0-0,0}], visibility = [4]D/ViewLifeTime: ViewLifeTime: [context, attrs]D/ViewLifeTime: onFinishInflate: D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbafc0 I.E..... R.....ID 0,0-0,0}], visibility = [4]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbafc0 V.E..... R.....ID 0,0-0,0}], visibility = [0]D/ViewLifeTime: onAttachedToWindow: D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onMeasure() called with: widthMeasureSpec = [10737429], heightMeasureSpec = [1073743422]D/ViewLifeTime: onSizeChanged() called with: w = [1080], h = [1598], oldw = [0], oldh = [0]D/ViewLifeTime: onLayout() called with: changed = [true], left = [0], top = [322], right = [1080], bottom = [1920]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]D/ViewLifeTime: onMeasure() called with: widthMeasureSpec = [10737429], heightMeasureSpec = [1073743422]D/ViewLifeTime: onLayout() called with: changed = [false], left = [0], top = [322], right = [1080], bottom = [1920]

    按Home键进入后台

    D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbafc0 I.E..... R....... 0,0-1080,1920}], visibility = [4]

    重新回到应用内

    D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [4]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbafc0 V.E..... R.....ID 0,0-1080,1920}], visibility = [0]ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]

    按back键返回

    D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onDetachedFromWindow: 
  3. gone

    重新回到应用内

    D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.alex.ui.ViewLifeTime{42d39300 G.ED.... ......I. 0,0-0,0}], visibility = [8]D/ViewLifeTime: ViewLifeTime: [context, attrs]ViewLifeTime: onFinishInflate: D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbfeb0 I.E..... R.....ID 0,0-0,0}], visibility = [4]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbfeb0 V.E..... R.....ID 0,0-0,0}], visibility = [0]D/ViewLifeTime: onAttachedToWindow: D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]

    按Home键进入后台

    D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbfeb0 I.E..... R....... 0,0-1080,1920}], visibility = [4]

    重新回到应用内

    D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [4]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cbfeb0 V.E..... R.....ID 0,0-1080,1920}], visibility = [0]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]

    按back键返回

    D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onDetachedFromWindow: 

其次再看一下直接new的view

D/ViewLifeTime: ViewLifeTime: [context]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cb63f8 I.E..... R.....ID 0,0-0,0}], visibility = [4]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cb63f8 V.E..... R.....ID 0,0-0,0}], visibility = [0]D/ViewLifeTime: onAttachedToWindow: D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onMeasure() called with: widthMeasureSpec = [1073742904], heightMeasureSpec = [1073743744]D/ViewLifeTime: onSizeChanged() called with: w = [1080], h = [1920], oldw = [0], oldh = [0]D/ViewLifeTime: onLayout() called with: changed = [true], left = [0], top = [0], right = [1080], bottom = [1920]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]D/ViewLifeTime: onMeasure() called with: widthMeasureSpec = [1073742904], heightMeasureSpec = [1073743744]D/ViewLifeTime: onLayout() called with: changed = [false], left = [0], top = [0], right = [1080], bottom = [1920]D/ViewLifeTime: onDraw() called with: canvas = [android.view.GLES20RecordingCanvas@42cd9770]

按home键进入后台

D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cb63f8 I.E..... R.....I. 0,0-1080,1920}], visibility = [4]

重新回到应用内

D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [4]D/ViewLifeTime: onVisibilityChanged() called with: changedView = [com.android.internal.policy.impl.PhoneWindow$DecorView{42cb63f8 V.E..... R.....ID 0,0-1080,1920}], visibility = [0]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [0]D/ViewLifeTime: onDraw() called with: canvas = [android.view.GLES20RecordingCanvas@42cd9770]D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [true]

按back键返回

D/ViewLifeTime: onWindowFocusChanged() called with: hasWindowFocus = [false]D/ViewLifeTime: onWindowVisibilityChanged() called with: visibility = [8]D/ViewLifeTime: onDetachedFromWindow: 

由测试可以看出
1.对于从xml中解析的view:如果visibility不是visible(默认值)时,会先回调onVisibilityChanged()(invisible 会设置为invisible,gone会设置成 visible),然后在调用构造方法

2.onVisibilityChanged()会被回调多次
visible: 会先设置为invisible 在改为visible
invisible: 在构造方法之前设置为invisible,构造方法之后先设置为invisible,再改为visible
gone:在构造方法之前设置为visible,构造方法之后先设置为invisible,再改为visible
不知道为什么最后一次都设置为了visible?难道是log顺序错

3.对于从xml中解析的需要注意onFinishInflate(),在解析过程中会根据xml中的配置设置view的属性,因此如果要在代码中设置view的参数,要在activity的onFinishInflate()方法中或之后的设置,防止被覆盖

4.onMeasure()和onLayout()会回调至少两次,在第一次回调onMeasure()后会回调onSizeChanged(),因此如果在自定义view中需要view的width 和 height可以再onSizeChanged中获得;在最后一次onLayout()之后会回调onDraw()绘制view

5.onAttachedToWindow() 和 onDetachedFromWindow()对应:可以在onDetachedFromWindow()中释放需要释放的资源

6.onWindowFocusChanged()监听view所在window的焦点情况,可以作为view是否在前台的标志

view 的主要生命周期为 onVisibilityChanged(被设置为不可见时)——> 构造 ——> onVisibilityChanged——> onFinishInflate ——> onAttachedToWindow ——> onMeasure ——> onSizeChanged ——> onLayout ——> onDraw ——> onVisibilityChanged——> onDetackedFromWindow

0 0
原创粉丝点击