上篇博客实现圆角对话框样式的Activity中提到,若需实现圆角对话框Activity,需要在Activity的onAttachedToWindow()函数中做文章,那么就想问:

  • onAttachedToWindow在整个Activity的生命周期中占据什么位置?
  • 为什么要在onAttachedToWindow中修改窗口尺寸?

一、onAttachedToWindow在Activity生命周期中的位置

根据之前分析API的套路,看onAttachedToWindow在Android文档中怎样介绍。

首先看Window.Callback中关于onAttachedToWindow的介绍。

public abstract void onAttachedToWindow ()

Called when the window has been attached to the window manager. See View.onAttachedToWindow() for more information.

好吧,官方把我引导到了View中,那么恭敬不如从命,看View中怎么说。

protected void onAttachedToWindow ()

This is called when the view is attached to a window. At this point it has a Surface and will start drawing. Note that this function is guaranteed to be called beforeonDraw(android.graphics.Canvas), however it may be called any time before the first onDraw -- including before or after onMeasure(int, int).

从API说明我们可以定位当View附加到窗体时,也就是View和Window绑定时就会调用这个函数,此时将会有一个Surface进行绘图之类的逻辑。并且发现Window.CallBack是一个接口类,而且官方引导到了View中,那么可以大胆判断View实现了Window.CallBack的回调方法,那么View和Window之间的关系便可以有个初步猜测。下篇博客再具体讨论DecorView和Window之间的关系。

接下来通过实验判断onAttachedToWindow在Activity整个生命周期中的位置。

实验很简单,将Activity各个生命周期打上log,然后看LogCat中的结果

看来我们最终要找的生命周期为onCreate->onStart->onResume->onAttachedToWindow

然后通过Google找到了一张比较详细的Activity生命周期图,也印证了我们的实验结论。

详见http://staticfree.info/~steve/complete_android_fragment_lifecycle.svg

二、为什么要在onAttachedToWindow中修改窗口尺寸

为什么网上很多教程一定要在onAttachedToWindow()里修改高宽而不在onCreate中?这个问题没人解答,那么我就将代码

  1. View view = getWindow().getDecorView();
  2. WindowManager.LayoutParams lp = (WindowManager.LayoutParams)view.getLayoutParams();
  3. lp.gravity = Gravity.CENTER;
  4. lp.width = (dm.widthPixels * 4) / 5;
  5. lp.height = (dm.widthPixels * 4) / 5;
  6. getWindowManager().updateViewLayout(view,lp);

放到onCreate中进行测试,结果在lp.gravity = Gravity.CENTER;这行报了空指针异常,所以view.getLayoutParams()获取的LayoutParams是空,那么问题来了!为什么onCreate()中DecorView的LayoutParams是空而onAttachedToWindow()中就不为空?要高清这个问题就要看DecorView在什么时候设置的LayoutParam。

从博客Android应用窗口的视图对象的创建过程分析中发现源码

  1. public final class ActivityThread {
  2. ......
  3. final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
  4. ......
  5. ActivityClientRecord r = performResumeActivity(token, clearHide);
  6. if (r != null) {
  7. final Activity a = r.activity;
  8. ......
  9. // If the window hasn't yet been added to the window manager,
  10. // and this guy didn't finish itself or start another activity,
  11. // then go ahead and add the window.
  12. boolean willBeVisible = !a.mStartedActivity;
  13. if (!willBeVisible) {
  14. try {
  15. willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
  16. a.getActivityToken());
  17. } catch (RemoteException e) {
  18. }
  19. }
  20. if (r.window == null && !a.mFinished && willBeVisible) {
  21. r.window = r.activity.getWindow();
  22. View decor = r.window.getDecorView();
  23. decor.setVisibility(View.INVISIBLE);
  24. ViewManager wm = a.getWindowManager();
  25. WindowManager.LayoutParams l = r.window.getAttributes();
  26. a.mDecor = decor;
  27. l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
  28. ......
  29. if (a.mVisibleFromClient) {
  30. a.mWindowAdded = true;
  31. wm.addView(decor, l);
  32. }
  33. }
  34. ......
  35. }
  36. ......
  37. }
  38. ......
  39. }

原来在ActivityThread执行handleResumeActivity时就会为PhoneWindow(r.activity.getWindow)中的DecorView设置LayoutParam,并且通过源码发现handleResumeActivity函数首先会执行performResumeActivity,此时会调用Activity的onResume()生命周期函数,这时问题就比较清晰了,看来只要在Activity的onResume生命周期后就能获取DecorView的LayoutParam,进而可以设置高度和宽度了。根据上面贴出的生命周期图,onResume()后面是onAttachedToWindow(),并且onAttachedToWindow只会调用一次,不会受用户操作行为影响。所以在onAttachedToWindow中进行窗口尺寸的修改再合适不过了。

总结:

    • onAttachedToWindow运行在onResume之后;
    • DecorView的LayoutParams是在ActivityThread的handleResumeActivity中设置的,并且该函数会调用Activity的onResume生命周期,所以在onResume之后可以设置窗体尺寸;

【转】onAttachedToWindow()在整个Activity生命周期的位置及使用的更多相关文章

  1. onAttachedToWindow()在整个Activity生命周期的位置及使用

    onAttachedToWindow在整个Activity的生命周期中占据什么位置? 为什么要在onAttachedToWindow中修改窗口尺寸? 一.onAttachedToWindow在Acti ...

  2. [转]: 两分钟彻底让你明白Android Activity生命周期(图文)!

    转自:http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在前 ...

  3. Activity生命周期(深入理解)

    今天看到一篇大神总结Activity的文章,内容甚为详细,特此转载http://www.cnblogs.com/lwbqqyumidi/p/3769113.html Android官方文档和其他不少资 ...

  4. Android Activity生命周期

    从android api文档摘抄出来的activity生命周期图如下: Activity有如下四种状态 a.活动状态  activity处于屏幕前台,获取到了焦点可以和用户进行交互,同一时刻只有一个a ...

  5. Android Activity生命周期详讲

    管理 Activity 生命周期 通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要. Activity 的生命周期会直接受到 Activity 与其他 Activit ...

  6. android Activity生命周期(设备旋转、数据恢复等)与启动模式

    1.Activity生命周期     接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行.暂停和停止三种状态,onCreate.onStart.onResume.o ...

  7. android开发------Activity生命周期

    这几天工作比较忙,基本没有什么时间更新播客了. 趁着今晚有点时间,我们来简单说一下什么是Activity生命周期和它们各阶段的特征 什么是生命周期 在还没有接触android开发的时候,听到有人说Ac ...

  8. 安卓activity生命周期

    相信不少朋友也已经看过这个流程图了,也基本了解了Activity生命周期的几个过程,我们就来说一说这几个过程. 1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法, ...

  9. Activity生命周期 onCreate onResume onStop onPause (转)

    Android应用开发提高系列(6)——Activity生命周期 onCreate 和 onResume 在程序启动时候都会启动, 所有有些需要在onCreate onResume中都要实现的功能,之 ...

随机推荐

  1. 深入攻克c语言--day04

    1.将包含字符数字的字符串分开,使得分开后的字符串前一部分是数字后一部分是字母.例 如“h1ell2o3” ->”123hello” #include<stdio.h> #inclu ...

  2. Mutual information and Normalized Mutual information 互信息和标准化互信息

    实验室最近用到nmi( Normalized Mutual information )评价聚类效果,在网上找了一下这个算法的实现,发现满意的不多. 浙江大学蔡登教授有一个,http://www.zju ...

  3. zabbix proxy安装及使用

    首先我萌先理解下为什么要突然冒出zabbix proxy 它是一个代理,也就是agent与server的中间层,他会代替server收集agent的数据保存起来,然后推送给server,那么很明显,它 ...

  4. HTML5/jQuery雷达动画图表 图表配置十分简单

    1.HTML5/jQuery雷达动画图表 图表配置十分简单 之前我们介绍过不少形形色色的HTML5图表了,像这款HTML5折线图表Aristochart是一款很不错的折线图表,这款HTML5 Canv ...

  5. 【eclipse插件开发实战】Eclipse插件开发7——插件发布jar包

    Eclipse插件开发7--插件发布jar包 最省事的方式就是直接导出jar包,然后放到eclipse的plugins目录下,重启eclipse即可. step1: 对需要打包的插件工程右击→导出(E ...

  6. VS中用C#开发应用程序的调试入门、技巧和实例(转载)

    入门篇 假设你是有着.Net平台的程序员,并且使用Visual Studio 做为开发工具. 断点:最简单的一种,设置一个断点,程序执行到那一句就自动中断进入调试状态.设置断点,在你觉得有问题的代码行 ...

  7. MFC中CArray类原理及其应用

    1.CArray类应用 函数简介CArray::GetSize int GetSize( ) const;取得当前数组元素个数. CArray::GetUpperBound int GetUpperB ...

  8. ZOJ3166【找环值最小】

    题意: 给你一幅图,要你找一个hotel能够满足出去回来,而且保证权值最小: 思路: 可以搜环,然后取最小权值环,拿个点: floyd方便,初始话自己到自己就是无穷,然后就枚举一下给出的hotel就好 ...

  9. uoj#268. 【清华集训2016】数据交互(动态dp+堆)

    传送门 动态dp我好像还真没咋做过--通过一个上午的努力光荣的获得了所有AC的人里面的倒数rk3 首先有一个我一点也不觉得显然的定理,如果两条路径相交,那么一定有一条路径的\(LCA\)在另一条路径上 ...

  10. Splay(区间翻转) 模板

    洛谷:P3391 [模板]文艺平衡树(Splay) #include<cstdio> #include<iostream> #include<algorithm> ...