【Android源码 栏目提醒】:网学会员为广大网友收集整理了,【eoe分享】Android4.0Launcher源码分析 - 其它资料,希望对大家有所帮助!
【专家专栏】
Android 4.0 Launcher
源码分析系列一............................................................1 【专家专栏】
Android 4.0 Launcher
源码分析系列二......................................................... 13 【专家专栏】
Android 4.0 Launcher
源码分析系列三......................................................... 20【专家专栏】
Android 源码分析系列【专家专栏】
Android 4.0 Launcher
源码分析系列一 2012-01-11 16:02 傻蛋 51CTO.com 我要评论2 字号:T T著名手机厂商
Android 开发工程师、最牛网站长傻蛋曾为51CTO 撰稿《
Android 4.0的图形硬件加速及绘制技巧》受到读者的广泛欢迎。
傻蛋同学将在新的一年里在 51CTO 开设专家专栏,本文为傻蛋正在研究的一个方向,与网友共同探讨
Android 4.0原生的桌面程序——Launcher。
AD: 从今天起傻蛋打算做一个系列文章,对最新的
Android 4.0 系统中的 Launcher,也就是
Android 4.0原生的桌面程序,进行一个深入浅出的分析,从而引领
Android 系统的编程爱好者对 Launcher 的设计思想,实现方式来做一个研究,从而能够通过这个实例最掌握到目前世界领先的设计方法,同时在程序中加入我们的一些新的实现。
众所周知,对一些优秀源代码的分析,是提高编程水平的一条便捷的方式,希望本系列文章能够给大家带来一定的启发,同时欢迎大家和作者一起讨论,作者的微博是:http://weibo.com/zuiniuwang/ 先 从 整 体 上 对 Launcher 布 局 作 一 个 分 析 , 让 我 们 通 过 查 看 Launcher.xml 和 使 用hierarchyviewer 布局查看工具两者结合的方法来对 Launcher 的整体结构有个了解。
通过hierarchyviewer 来对整个桌面做个截图,如下: 放大后如下所示: 可以看到整个桌面包含的元素,最上面是 Google 的搜索框,下面是一个始终插件,然后是图标,再有就是一个分隔线,最后是 dock。
请注意,桌面程序其实并不包含桌面壁纸,桌面壁纸其实是由 WallpaperManagerService 来提供,整个桌面其实是叠加在整个桌面壁纸上的另外一个层。
点击查看大图整个 Launcher.xml 布局文件如下:1 ltcom.
android.launcher2.DragLayer2 xmlns:androidquothttp://schemas.
android.com/apk/res/androidquot3xmlns:launcherquothttp://schemas.
android.com/apk/res/com.
android.launcherquot45
android:idquotid/drag_layerquot6
android:layout_widthquotmatch_parentquot7 gt
android:layout_heightquotmatch_parentquotgt89 lt-- Keep these behind the workspace so that they are not visible when10 gt we go into AllApps --gt11 ltinclude12
android:idquotid/dock_dividerquot13 layoutquotlayout/workspace_dividerquot14
android:layout_widthquotmatch_parentquot15
android:layout_heightquotwrap_contentquot16
android:layout_marginBottomquotdimen/button_bar_heightquot17
android:layout_gravityquotbottomquot /gt18 ltinclude19
android:idquotid/paged_view_indicatorquot20 layoutquotlayout/scroll_indicatorquot21
android:layout_widthquotwrap_contentquot22
android:layout_heightquotwrap_contentquot23
android:layout_gravityquotbottomquot24
android:layout_marginBottomquotdimen/button_bar_heightquot /gt2526 lt-- The workspace contains 5 screens of cells --gt27 ltcom.
android.launcher2.Workspace28
android:idquotid/workspacequot29
android:layout_widthquotmatch_parentquot30
android:layout_heightquotmatch_parentquot31
android:paddingTopquotdimen/qsb_bar_height_insetquot32
android:paddingBottomquotdimen/button_bar_heightquot33 launcher:defaultScreenquot2quot34 launcher:cellCountXquot4quot35 launcher:cellCountYquot4quot36 launcher:pageSpacingquotdimen/workspace_page_spacingquot37launcher:scrollIndicatorPaddingLeftquotdimen/workspace_divider_padding_leftquot38launcher:scrollIndicatorPaddingRightquotdimen/workspace_divider_padding_right gtquotgt39 40 ltinclude
android:idquotid/cell1quot layoutquotlayout/workspace_screenquot /gt 41 ltinclude
android:idquotid/cell2quot layoutquotlayout/workspace_screenquot /gt 42 ltinclude
android:idquotid/cell3quot layoutquotlayout/workspace_screenquot /gt 43 ltinclude
android:idquotid/cell4quot layoutquotlayout/workspace_screenquot /gt 44 ltinclude
android:idquotid/cell5quot layoutquotlayout/workspace_screenquot /gt 45 lt/com.
android.launcher2.Workspacegt 46 47 ltinclude layoutquotlayout/hotseatquot 48
android:idquotid/hotseatquot 49
android:layout_widthquotmatch_parentquot 50
android:layout_heightquotdimen/button_bar_height_plus_paddingquot 51
android:layout_gravityquotbottomquot /gt 52 53 ltinclude 54
android:idquotid/qsb_barquot 55 layoutquotlayout/qsb_barquot /gt 56 57 ltinclude layoutquotlayout/apps_customize_panequot 58
android:idquotid/apps_customize_panequot 59
android:layout_widthquotmatch_parentquot 60
android:layout_heightquotmatch_parentquot 61
android:visibilityquotinvisiblequot /gt 62 63 ltinclude layoutquotlayout/workspace_clingquot 64
android:idquotid/workspace_clingquot 65
android:layout_widthquotmatch_parentquot 66
android:layout_heightquotmatch_parentquot 67
android:visibilityquotgonequot /gt 68 69 ltinclude layoutquotlayout/folder_clingquot 70
android:idquotid/folder_clingquot 71
android:layout_widthquotmatch_parentquot 72
android:layout_heightquotmatch_parentquot 73
android:visibilityquotgonequot /gt 74 lt/com.
android.launcher2.DragLayergt Launcher 整个布局的根是 DragLayer,DragLayer 继承了 FrameLayout,所以 DragLayer 本身可以看作是一个 FrameLayout。
下面是 dock_divider,它通过 include 关键字包含了另外一个布局文件 workspace_divider.xml ,而这个 workspace_divider.xml 包含了一 ImageView,其实 dock_divider 就是 dock 区域上面的那条直线。
再下面是 paged_view_indicator,同样它包含了 scroll_indicator.xml,其中包含了一个ImageView,显示的是一个.9的 png 文件。
实际上就是当 Launcher 滚动翻页的时候,那个淡蓝色的页面指示条。
然后桌面的核心容器 WorkSpace,如下图所示,当然你看到的只是 Workspace 的一部分,其 实 是 一 个 workspace_screen , 通 过 Launcher.xml 可 以 看 到 , 整 个 workspace 由 5 个workspace_screen 组 成 , 每 个 workspace_screen 其 实 就 是 对 应 桌 面 一 页 。
而 每 个workspace_screen 包含了一个 CellLayout,这是一个自定义控件,继承自 ViewGroup,所以它算是一个用来布局的控件,在这里主要用来承载我们每页的桌面图标、widget 和文件夹。
点击查看大图 通过查看如下的布局结构(由于图太大只截取了一部分)可以看到, Workspace 包含了序号从0到4的5个 CellLayout。
接下来是一个 Hotseat其实就是这块 dock 区域了。
如图所示: 点击查看大图 从如下的布局图我们可以看到,这个 Hotseat 其实还是包含了一个 CellLayout,用来承载4个图标和中间启动所有程序的按钮。
再下来就是那个 qsb_bar,就是屏幕最顶端的 Google 搜索框。
这个搜索框是独立于图标界面的,所以当我们对桌面进行翻页的时候,这个搜索框会巍然不动滴固定在最顶端,如下所示: 紧接着是3个初始化时被隐藏的界面。
apps_customize_pane,点击 dock 中显示所有应用程序的按钮后才会从隐藏状态转换为显示状态,如下图所示,显示了所有应用程序和所有插件的界面。
点击查看大图 通过查看 apps_customize_pane.xml ,我们可以看到 apps_customize_pane 主要由两部分组成: tabs 部分, tabs_container 和 tabcontent。
用来让我们选择是添加应用程序还是 widget,如下图所示: 点击查看大图 tabcontent,选择了相应的 tab 之后,下面的部分就会相应的显示应用程序或是 widget 了,如下图所示:点击查看大图 workspace_cling 和 folder_cling 是刚刷完机后,进入桌面时,显示的使用向导界面,介绍怎么使用 workspace 和 folder,跳过以后就再也不会出现了,这里就不截图了。
】 【51CTO.com 独家特稿,非经授权谢绝转载,合作媒体转载请注明原文作者及出处! 【编辑推荐】 75 【专家专栏】
Android 4.0 Launcher
源码分析系列二 76 【专家专栏】
Android 4.0 Launcher
源码分析系列三 77
Android 4.0的图形硬件加速及绘制技巧【专家专栏】
Android 源码分析系列【专家专栏】
Android 4.0 Launcher
源码分析系列二 2012-02-02 15:56 傻蛋 51CTO.com 我要评论0 字号:T T本文为笔名“傻蛋”的51CTO 特约专家的《
Android 4.0 Launcher
源码分析系列》专栏的第二篇,这一节傻蛋将从整个 Laucher 的入口点入手,同时 Laucher 在加载了它的布局文 件Laucher.xml 时都干了些什么。
AD: 【51CTO.com 2月2日独家特稿】上一节我们研究了 Launcher 的整体结构,这一节我们看看整个 Laucher 的入口点,同时 Laucher 在加载了它的布局文件 Laucher.xml 时都干了些什么。
我们在源代码中可以找到 LauncherApplication, 它继承了 Application 类,当整个Launcher 启动时,它就是整个程序的入口。
我们先来看它们在 AndroidManifest.xml 中是怎么配置的。
1 ltapplication 2
android:namequotcom.
android.launcher2.LauncherApplicationquot 3
android:labelquotstring/application_namequot 4
android:iconquotdrawable/ic_launcher_homequot 5
android:hardwareAcceleratedquotbool/config_hardwareAcceleratedquot 6
android:largeHeapquotbool/config_largeHeapquotgt 首 先 通 过
android:name 指 定 了 整 个 Launcher 的 Application 也 就 是 入 口 是 在com.
android.launcher2.LauncherApplication 这个路径下,
android:lable 指定了桌面的名字是叫 Launcher如果要改名字就改 values 文件夹的 string.xml 中的相应属性就可以了。
android:icon 指定了 Laucher 的图标,这个图标可以在应用程序管理器中看见,如下图所示,是个可爱机器人住在一个小房子里面,如果需要更改 Laucher 的图片,重新设置这个属性就可以了。
android:hardwareAcceleratedquotbool/config_hardwareAcceleratedquot 指定了整个应用程序是启用硬件加速的,这样整个应用程序的运行速度会更快。
android:largeHeapquotbool/config_largeHeapquot 指定了应用程序使用了大的堆内存,能在一定程度上避免,对内存 out of memory 错误的出现。
我们可以在 values 文件夹的 config.xml中看到对是否启用硬件加速和大内存的配置。
如下所示: 7 gt lt/boolgt ltbool namequotconfig_hardwareAcceleratedquotgttruelt/boolgt 8 gt lt/boolgt ltbool namequotconfig_largeHeapquotgtfalselt/boolgt 在 Application 中 onCreate 方 法 通 过 : sIsScreenLarge screenSize Configuration.SCREENLAYOUT_SIZE_LARGE screenSize Configuration.SCREENLAYOUT_SIZE_XLARGE 和 sScreenDensity getResources.getDisplayMetrics.density来判断是否是大屏幕,同时得到它的屏幕密度。
同时通过 mIconCache new IconCachethis 来设置了应用程序的图标的 cache,然后申明了 LauncherModel,mModel new LauncherModelthis mIconCache LauncherModel 主要用于加载桌面的图标、插件和文件夹,同时 LaucherModel 是一个广播接收器,在程序包发生改变、区域、或者配置文件发生改变时,都会发送广播给 LaucherModel,LaucherModel 会根据不同的广播来做相应加载操作,此部分会在后面做详细介绍。
在 LauncherApplication 完成初始化工作之后,我们就来到了 Launcher.java 的 onCreate方法,同样是启动桌面时的一系列初始化工作。
首先需要注意的是在加载 launcher 布局文件时的一个 TraceView 的调试方法,它能够对在他们之间的方法进行图形化的性能分析,并且能够具体到 method 代码如下: 9 if PROFILE_STARTUP 10
android.os.Debug.startMethodTracing 11 Environment.getDataDirectory quot/data/com.
android.launcher/launcherquot 12 13 if PROFILE_STARTUP 14
android.os.Debug.stopMethodTracing 15 我指定的生成性能分析的路径是:/data/data/com.
android.launcher/launcher,启动launcher 后我们会发现在指定的目录下生成了 launcher.trace 文件,如下图所示: 在 把 launcher.trace 文件通过 DDMS pull 到电脑上, SDK 的 tools 目录里,执行 traceview工具来打开 launcher.trace .如下图所示: 点击查看大图 可以看到 setContentView 使用了448.623ms,占整个跟踪代码时间的62,所以说在加载布局文件时,肯定经过了一系列的加载运算,我们接着分析。
当加载 launcher 布局文件的过程时,最为关键的时对整个 workspace 的加载,workspace是一个自定义组件,它的继承关系如下所示,可以看到 Workspace 实际上也是一个 ViewGroup,可以加入其他控件。
当 ViewGroup 组件进行加载的时候首先会读取本控件对应的 XML 文件,然后 Framework 层会执行它的 onMeasure方法,根据它所包含的子控件大小来计算出整个控件要在屏幕上占的大小。
Workspace 重写了 ViewGroup 的 onMeasure 方法在 PagedView 中,在 workspace 中是对5个子 CellLayout 进行测量,的方法如下 具体含义请看注释: 16 Override 17 protected void onMeasureint widthMeasureSpec int heightMeasureSpec 18 if mIsDataReady 19 super.onMeasurewidthMeasureSpec heightMeasureSpec 20 return 21 22 //得到宽度的模式(在配置文件中对应的是 match_parent 或者 wrap_content)和其 大小 23 final int widthMode MeasureSpec.getModewidthMeasureSpec 24 final int widthSize MeasureSpec.getSizewidthMeasureSpec 25 //宽度必须是 match_parent否则会抛出异常。
26 if widthMode MeasureSpec.EXACTLY 27 throw new IllegalStateExceptionquotWorkspace can only be used inEXACTLY mode.quot28 2930 / Allow the height to be set as WRAP_CONTENT. This allows the particularcase31 of the All apps view on XLarge displays to not take up more spacethen it needs. Width32 is still not allowed to be set as WRAP_CONTENT since many parts ofthe code expect33 each page to have the same width.34 /35 //高度允许是 wrap_content因为在大屏幕的情况下,会占了多余的位置36 final int heightMode MeasureSpec.getModeheightMeasureSpec37 int heightSize MeasureSpec.getSizeheightMeasureSpec38 int maxChildHeight 039 //得到在竖值方向上和水平方向上的 Padding40 final int verticalPadding mPaddingTop mPaddingBottom41 final int horizontalPadding mPaddingLeft mPaddingRight424344 // The children are given the same width and height as the workspace45 // unless they were set to WRAP_CONTENT46 if DEBUG Log.dTAG quotPagedView.onMeasure: quot widthSize quot quot heightSize quot mPaddingTopquotmPaddingTop quot mPaddingBottomquotmPaddingBottom47 final int childCount getChildCount48 //对 workspace 的子 View 进行遍历,从而对它的几个子 view 进行测量。
49 childCount for int i 0 i lt childCount i 50 // disallowing padding in paged view just pass 051 final View child getPageAti52 final LayoutParams lp LayoutParams child.getLayoutParams5354 int childWidthMode55 if lp.width LayoutParams.WRAP_CONTENT 56 childWidthMode MeasureSpec.AT_MOST57 else 58 childWidthMode MeasureSpec.EXACTLY59 6061 int childHeightMode62 if lp.height LayoutParams.WRAP_CONTENT 63 childHeightMode MeasureSpec.AT_MOST64 else 65 childHeightMode MeasureSpec.EXACTLY66 6768 final int childWidthMeasureSpec 69 MeasureSpec.makeMeasureSpecwidthSize - horizontalPadding childWidthMode 70 final int childHeightMeasureSpec 71 MeasureSpec.makeMeasureSpecheightSize - verticalPadding childHeightMode 72 //对子 View 的大小进行设置,传入 width 和 height 参数 73 child.measurechildWidthMeasureSpec childHeightMeasureSpec 74 maxChildHeight Math.maxmaxChildHeight child.getMeasuredHeight 75 if DEBUG Log.dTAG quottmeasure-childquot i quot: quot child.getMeasuredWidth quot quot 76 child.getMeasuredHeight 77 78 79 if heightMode MeasureSpec.AT_MOST 80 heightSize maxChildHeight verticalPadding 81 82 //存储测量后的宽度和高度 83 setMeasuredDimensionwidthSize heightSize 84 85 // We cant call getChildOffset/getRelativeChildOffset until we set the me.
上一篇:
安卓航班Android开发经典教程大总结1
下一篇:
韩国婚纱照片模板下载