Launcher分析
1.AndroidMainifest.xml
a) 通过original-package指定原始package
b) 定义了permisson,所属于的permissionGroup为android.permission-group.SYSTEM_TOOLS
PRELOAD_WORKSPACE 需要签名一致,且为system
INSTALL_SHORTCUT dangerous 需要用户确认
UNINSTALL_SHORTCUT dangerous 需要用户确认
READ_SETTINGS 自动授予权限 normal
WRITE_SETTINGS 自动授予权限 normal
http://www.verydemo.com/demo_c89_i24835.html
c) 使用了permission
使用了权限
CALL_PHONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
VIBRATE
BIND_APPWIDGET
GET_ACCOUNTS
READ_SETTINGS
WRITE_SETTINGS
d) 定义application
支持硬件加速,不使用大堆,支持rtl
e) 定义了主界面Launcher
为singleTask
android:clearTaskOnLaunch启动的时候把Task给清空
android:stateNotNeeded 不保存onSaveInstancestate,onCreate传null
f) 定义WallpaperChooser Activity
出现系统关闭dialog时finish activity
开启进程:wallpaper_chooser,代表私有进程
有个meta,设置默认的preview图片
g) 定义了 广播接收器
PreloadReceiver,定义permission为PRELOAD_WORKSPACE,接收为PRELOAD_WORKSPACE
InstallShortcutReceiver,permission为INSTALL_SHORTCUT
UninstallShortcutReceiver,permission为UNINSTALL_SHORTCUT
UserInitializeReceiver,data scheme为package,接受有PACKAGE_CHANGED,PACKAGE_REPLACED,PACKAGE_REMOVED
h) 定义了LauncherProvider
权限为"com.android.launcher2.settings
能被其他程序调用
设置外部读写权限需配置为WRITE_SETTINGS,READ_SETTINGS
i) 设置了meta-data
Nfc不可用
2.LauncherApplication
a) 继承Application,是主程序的入口
b) onCreate
1.获取是否是largescreen和screendensity
2.创建WidgetPreviewLoader CacheDb(widgetpreviews.db,table为shortcut_and_widget_previews)
name |
size |
preview_bitmap |
TEXT |
TEXT |
BLOB |
3.创建IconCache,获取默认app icon
4.创建LauncherModel,带入了IconCache
5.注册ACTION_PACKAGE_ADDED,ACTION_EXTERNAL_APPLICATIONS_AVAILABLE,ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE,ACTION_LOCALE_CHANGED,ACTION_CONFIGURATION_CHANGED,INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED,INTENT_ACTION_SEARCHABLES_CHANGED到LauncherModel
6.设置favorite数据的Observer为mFavoritesObserver,监听onChange操作,如果有改变则导致LauncherModel重新开始加载
c) onTerminate
取消LauncherModel receiver
取消ContentObserver
3.Launcher主activity
OnCreate
a) 使用严格模式
http://tech.it168.com/a2011/0908/1243/000001243936.shtml
b) 创建DragController,带入Launcher
c) 获取LayoutInflater
d) 获取AppWidgetManager,开启listener
e) 开启AsyncTask,不断读取LocaleConfiguration(launcher.preferences)locale,mcc,mnc
f) 设置R.layout.launcher
g) 初始化view
h) 显示第一次启动的workspaceCling
i) 注册内容监视器AppWidgetResetObserver
content://com.android.launcher2.settings/appWidgetReset
j) 锁定所有的app
k) 保存instance state
l) 如果状态没有restoring(onResume),如果离开了laucher,则异步加载,否则同步加载当前页(LaucherModel),会回调
m) 如果所有的app还没被加载,inflate R.layout.apps_customize_progressbar
n) 创建SpannableStringBuilder,设置selection
o) 注册ACTION_CLOSE_SYSTEM_DIALOGS到CloseSystemDialogsIntentReceiver
i. 关闭窗口内所有对话组件getWindow().closeAllPanels()
p) 根据垂直还是水平显示global icons
q) 发送屏幕rotation setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
OnStart
a)设置FirstFrameAnimatorHelper visible为true
onPause
a)设置wallpaper visibility为true,设置launcherView(最外层的framelayout)的background
b)DragController会cancelDrag
c)DragController会resetLastGetureUpTime
OnResume
a) 记录时间
b) 当前onResumeState的状态为WORKSPACE(显示workspace)还是APPS_CUSTOMIZE(显示app),然后重置为none
c) 设置workspace(launcherView,最外层的framelayout)的background
d) 对于放在队列(xml) 中的快捷方式,触发install
e) 如果需要加载,触发LauncherModel的startLoader
f) 回调reusumecallbacks
g) 重新设置workspace和apps customize的drawable state
h) 重新设置workspace下Celllayout的ShortcutAndWidgetContainer
i) 更新globalIcons
OnStop
a)设置FirstFrameAnimatorHelper visible为false
LauncherModel.Callbacks
setLoadOnResume: 当activity触发onPause时,触发mOnResumeNeedsLoad,告知需要在onResume时重新加载loader
getCurrentWorkspaceScreen:获取Workspace当前页
startBinding:把所有的celllayout和widget,shortcut清除掉
bindItems:等待onResume时,把application,shortcut,folder等加入workspace
bindFolders:等待onResume时,把folder清除掉,放入新的folder
finishBindingItems:等待onResume时,记载完毕,做动画,告知workspaceloading为false,同时划到当前页
bindAppWidget:等待onResume时,绑定appwidget,加入workspace
bindAllApplications:把所有ApplicationInfo加载到appcustomizeContent里面(AppsCustomizePagedView)
bindAppsAdded:等待onResume时,把app list加入到appsCustomizeContent
bindAppsUpdated:等待onResume时,把ApplicationInfo list到workspace和appscustomizeContent
bindComponentsRemoved:等待onResume时,把要删除package list从workspace和appsCustomizeContent里面删除掉,同时回调告诉DragController(onAppsRemoved)
bindPackagesUpdated:等待onResume时,更新appscustomizeContent
isAllAppsVisible:看当前state是否为APPS_CUSTOMIZE或者APPS_CUSTOMIZE(分NONE,WORKSPACE,APPS_CUSTOMIZE,APPS_CUSTOMIZE_SPRING_LOADED)
isAllAppsButtonRank:hotseat是否app有button rank
bindSearchablesChanged:更新GlobalSearchIcon,VoiceSearchIcon,回调SearchDropTargetBar的onSearchPackagesChanged
onPageBoundSynchronously:把page加入到SyncronouslyBoundPages里面,当onRestoreInstanceState时,遍历SyncronouslyBoundPages,并调用restoreInstanceStateForChild
4.WallpaperChooser
a) Layout为R.layout.wallpaper_chooser_base
b) Layout里面主要是WallpaperChooserDialogFragment
c) WallpaperChooserDialogFragment
i. 提供newInstance创建WallpaperChooserDialogFragment
ii. onCreateDialog
从R.array.wallpapers和R.array.extra_wallpapers查找图片
找到图片加入到image和thumbs成员数组中
onCreateView
加载R.layout.wallpaper_chooser,用Gallery显示,Gallery用R.layout.wallpaper_item(一个imageview),点击按钮通过WallpaperManager,把resource设置,并退出activity
onDismiss
取消WallpaperLoader AsyncTask
onDetach
取消WallpaperLoader AsyncTask
onDestroy
取消WallpaperLoader AsyncTask
iii. Gallery点击选中
开启WallpaperLoader AsyncTask,主要是解析图片
d)
5.PreloadReceiver
a) 获取LaucherApplication和LauncherProvider
b) 调用LauncherProvider的loadDefaultFavoritesIfNecessary,开启加载workspace资源
6.InstallShortcutReceiver
a) 接收Intent的EXTRA_SHORTCUT_INTENT,EXTRA_SHORTCUT_NAME,EXTRA_SHORTCUT_ICON,EXTRA_SHORTCUT_ICON_RESOURCE
b) 创建PendingInstallShortcutInfo保存过来的信息
c) 获取com.android.launcher2.prefs sharedpreferences
d) 根据lanucher是否加载,如果未加载则加入到xml里面作为队列
e) 如果已经加载,则通过LauncherModel 让其workerthread flush,然后
获取数据库favorites表里面的itemtype,container,screen,cellx,celly,spanx,spany,同时查询是否已经存在这快捷方式在数据库里面
f) 通过中间页开始查找可放置的地方
首先查找当前页是否有empty的cell,通过CellLayout的findVacantCell,找到后,通过LauncherModel的addShortcut,把坐标还有screen 记录到favorite表中
7.UninstallShortcutReceiver
a) 创建PendingUninstallShortcutInfo,如果使用mUninstallQueue,加入uninstallqueue中
b) 跟InstallShortcutReceiver一样,从com.android.launcher2.prefs 获取sp
c) 在数据库favorites表中删除数据
8.UserInitializeReceiver
a) 添加wallpaper到wallpapermanager里面
9.PackageChangedReceiver
a) 通过WidgetPreviewLoader删除shortcut_and_widget_previews(widgetpreviews.db)数据
10.LauncherProvider
a) 继承ContentProvider,authority为com.android.launcher2.settings, db名字为launcher.db,table有favorites,同时一个AppWidgetHost(容纳AppWidget的地方)
title |
intent |
container |
screen |
cellX |
cellY |
spanX |
spanY |
itemType |
appWidgetId |
TEXT |
TEXT |
INTEGER |
INTEGER |
INTEGER |
INTEGER |
INTEGER |
INTEGER |
INTEGER |
INTEGER |
isShortcut |
iconType |
iconPackage |
iconResource |
icon |
uri |
displayMode |
|
|
|
INTEGER |
INTEGER |
TEXT |
TEXT |
BLOB |
TEXT |
INTEGER |
|
|
|
b) 设置LauncherApplication的LauncherProvider为本对象,对appwidget重新设置,
c) 迁移旧表数据
d) onUpgrade,根据不同版本更新数据库表
11.LauncherModel
a) 继承BroadcastReceiver
b) 创建launcher-loader的workerthread(HandlerThread)
c) 构造函数:
i. 创建AllAppsList(带入iconCache)
ii. 创建默认的icon
iii. 查看配置看是否所有app是否load delay
d) OnReceive
i. ACTION_PACKAGE_CHANGED/REMOVED/ADDED/EXTERNAL_APPLICATIONS_AVAILABLE/EXTERNAL_APPLICATIONS_UNAVAILABLE/LOCALE_CHANGED/
然后launcher-loader workerthread处理PackageUpdatedTask
ii. LOCALE_CHANGED, CONFIGURATION_CHANGED
e) PackageUpdatedTask
i. 状态有OP_NONE,OP_ADD,OP_UPDATE,OP_REMOVE,OP_UNAVAILABLE
ii. OP_ADD:把所有packages加入到AllAppslist里面
OP_UPDATE:更新AllAppslist packages信息,并删除widgetPreviewLoader db数据
OP_REMOVE:
OP_UNAVAILABLE:删除AllAppslist的package,同样删除widgetPreviewLoader db数据
iii. 回调状态给callbacks(Launcher Activity),
如果有added,回调bindAppsAdded
如果有modified,回调bindAppsUpdated
如果有remove,回调bindComponentsRemoved
对于widgets和shortcuts的,回调bindPackagesUpdated
f) AllAppsList
i. 记录着ApplicationInfo,包括added,removed,modified做为中间状态,记录时候做了什么操作
g) LoaderTask:
i. 第一步,如果是workspacefirst,加载workspace,如果不需要,则加载所有app
加载workspace:
在favorite,加载数据
数据有sBgWorkspaceItems,sBgAppWidgets,sBgFolders,sBgItemsIdMap,
sBgDbIconCache
ITEM_TYPE_APPLICATION/ITEM_TYPE_SHORTCUT:sBgWorkspaceItems,如果在folder,则为sBgFolders
ITEM_TYPE_FOLDER:sBgFolders
ITEM_TYPE_APPWIDGET:sBgAppWidgets
绑定workspace:
第一步:告诉workspqce准备binding (callbacks(Launcher)的startBinding)
第二步:加载绑定当前页
回调bindItem
回调bindFolders
回调bindAppWidget
第三步:回调onPageBoundSynchronously
第四步:绑定其他workspace item
第五步:结束,回调finishBindingItems
加载apps:
从packageManager获取app到mBgAllAppsList(AllAppsList),根据名字排序
同时回调到callback(Launcher)的bindAllApplications,bindAppsAdded,
绑定所有app,回调callbacks(Launcher)的bindAllApplications
ii. 等待空闲,通过wait和notify
iii. 第二步,如果是workspacefirst,加载所有app,不是则加载workspace
iv. 第三步,更新所有bg db icon cache
v. 第四步,删除自身,退出
12.IconCache,主要把图标和title放在Hashmap中
13.WidgetPreviewLoader.CacheDb
a) 获取LauncherApplication的iconcache和widgetpreviewcachedb
b) 创建loadedPreviews弱引用的Hashmap和unusedbitmaps的软引用hashmap
c)
14.