工作需要这几天看了4.3 源码下的Launcher2应用,因为需要自定义应用风格,自然需要了解Launcher加载应用信息的流程,Widget的还没有涉及,以后可能也会研究,先把应用图标界面的加载流程整理下,供后续研究参考。
网上的Launcher相关的资料基本上把原生态下各个部分所对应的文件分析的比较透彻了,也就是Launcher.xml文件中的各种组件分别代表界面上的何种组件,workspace和workscreen的关系,hotseat和folder_cling都在哪,非常清晰明了,本人比较关注应用图标界面,于是发现了Launcher.xml下的apps_customize_pane布局。
目前的Luancher其实可以认为存在两个基本模式,workspace和TabContainer,工作模式和应用程序模式,切换的关键就是hotseat中的那个那个应用图标,workspcae不是本文关注点,暂时忽略,重点是点击hotseat中的应用程序后,应用程序们的信息是如何被获取加载的。
有必要先瞅瞅相关的类结构
相关的类结构主要分成三大部分
1 环境,Launcher是整个应用的基本Activity,在这个大环境中可以做应用的状态切换,这种切换可能是以某些布局的隐藏或者显示来实现的,应用刚启动时是在workspace状态,在最底下的hotseat中有一些应用热图标,这些都可以找到对应配置文件自定义,中间的那个一个圈六个点的应用程序图标,ic_allapps,比较关键。
2 接口,在应用图标的加载流程中,涉及到一个动画的接口,LauncherTransitionable
接口是一种协议行为规范,任何对象实现了该接口都可以定义自己在完成动画准备、开始、继续、结束后的一些列操作,通过该方式实现松耦合,环境不需要知道对象是啥,只会在合适的时候要求对象完成相关操作。Launcher应用两种状态(AppsCustomizeTabHost和Workspace)都是该接口类型对象。
参数l表示Launcher对象,animated是个动画开关提示,表示是否采用动画方式进行状态切换,toWorkspace,是否是切换到工作区模式。
3 应用程序模式对象
从工作区模式切换到应用程序模式,显示的是个Tab界面,整个Tab是在AppsCustomizeTabHost中定义的,在Tab的主界面,是个app和Widget公用的pagedView,原生态系统默认是把app显示在Widegt的前面,在该PageView中,sync函数家族比较重要,主要是把数据源加载到对应的item中,mApps是一个应用信息列表,在Launcher刚刚启动时,通过LauncherModel的startLoader将系统中的应用信息统一读取并放入到该数组列表中。本文重点在app,widget会在以后整理。
具体流程
分析完类结构后,流程就比较清晰了,默认启动时显示在工作区模式,从用户点击hotseat中的应用图标开始。
1 Launcher Acitivity在启动时,通过setView将Hotseat加载,点击时,Hotseat中的应用icon调用了Launcher的onClickAllAppsButton方法
2 Launcher在该方法中进行类内部方法传递,传递流程如下:
该方法内部包含了从工作区模式到应用程序模式的状态切换参数,toView是个关键参数,表示要切换的模式对象,AppsCustomizeTabHost就是即将进入的目标状态,上文提到,该目标对象实现了LauncherTransitionable接口,这样在动画的不同状态时,Launcher就会调用AppsCustomizeTabHost的不同接口实现,继续内部传递流程
类似于状态分发,在动画效果结束后,调用toView的接口操作
在动画状态结束后,TabHost会调用接口操作。
3 AppsCustomizeTabHost中的接口操作,主要是让其中的PageView装载对应的page的数据,切换后的pageView中,包含了一些app和widget的Grid显示,每一页都会有对应的显示,这些数据都是存储在特点的数据结构中,该TabHost会判断当前处于那个page,并要求pageView将该page的数据加载到对应的对象中去。
4 AppsCustomizePagedView,这是显示TabHost中的pageView对象,往上走两步,继承自PageView,该自定义控件家族定义了可以左右滑动的PageView控件,有兴趣的同学可以研究该自定义控件族,loadAssociatedPages会调用父类对于方法,经过一些列的家族类内部方法传递(类似上述),调用了AppsCustomizePagedView的下述方法
这个方法比较清晰的显示了上述过程,nNumAppsPages表示app所占的page数,当当前page数小于该值时,装载Apps的方法,否则就是Widget。syncAppsPageItems这个方法就是将本page所对应的应用数据加载到对应控件的方法了,mApps是Launcher在启动时通过查询而建立的应用信息,该方法通过将mApps中位于该页的信息取出,并将其应用到代表UI上具体应用图标的PagedViewIcon中,这是个重写的TextView,我们在UI上所见到的图标Grid,每一项都是一个PageViewIcon,syncAppsPageItems方法如下:
相关流程结束,简单画了个流程图,只标示了对象间流转步骤如下:
收尾
本文并没有详尽分析4.3的Launcher源码,而是针对应用App加载分析了相关结构及流程,对于LauncherModel在启动时的数据查询及应用数据列表建立也未详细分析,整理本文的目的是为了清晰Launcher在应用模式下App加载相关内容,为以后自定义做铺垫,基于Widget的整理分析也会在以后陆续分享。
~版权所有~转载请注明~