**launcher3是在Launcher2的基础上进化的版本,从Android 4.4 开始就使用Launcher3 .(kk版,kk2版)作为桌面使用,以前我们都在使用Launcher2,我们使用的是KK版本,具体区别后面再说. **
1.5 默认不支持预置APPWidget,需要用户指定权限.
在目前Launcher3 的架构上,会有些客至化受限制或者存在bug.
2.1 无法预置空白的workspace页面,主要是与动态增减页面数量相冲突.
2.2 如果预置workspace页面大于一页,无法指定非第一页为主页面,主要是与动态增减页面数量相冲突,导致Exception;
2.3 安装到SD卡的应用,桌面创建快截图标后,关机再开机如果SD卡挂载慢,桌面快截图标会消失,包括Folder中图标也类试,这是Google Default 设计.
2.4 Launcher2 循环滑动功能在Launcher3 bug很多无法解决,主要由于Launcher3 Workspace结构大修改,目前无法做到有效的循环滑动,Launcher3暂时不支持.
#二.Launcher3 启动流程:
Activity Manager通过发送Intend来启动Launcher。
Intent intent = new Intent(mTopAction, mTopData != null ?
Uri.parse(mTopData) : null); intent.setComponent(mTopComponent);
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL){
intent.addCategory(Intent.CATEGORY_HOME);
}
startActivityLocked(null, intent, null, null, 0, aInfo, null, null, 0, 0, 0, false, false);
因此,如果你要开机启动一个替换Launcher的程序,只要在程序里面加入action.MAIN 、category.HOME、category.DEFAULT就可以。如果出现多个程序都加入这种intent,系统会弹出让你选择哪个作为启动器。```
##Launcher3 初始化:、
1.1 Launcher2初始化判断屏幕大小 屏幕密度以及BroadcastReceive和ContentObserver的注册都在整个程序的开始就完成了,是在LauncherApplication.java 里面,Launcher3 封装到了LauncherAppState里面了,在LauncherApplication.java里面获取实例.
1.2 然后就是初始化Launcher.java类 初始化加载预置apk
Widget.
LauncherProvider: Launcher的数据库,一个contentprovider里面存储了桌面的item信息, loadFavorites()会解析xml 目录下的default_workspace.xml文件,把读出来的内容写到数据库中,这样就做到了桌面的预置.
在default_workspace.xml中加载我们需要定制的apk,widget :
预置Widget:
如果widget需要的宽度大于Launcher 桌面配置的n 个cell格子宽度,这个widget就无法再Launcher的列表显示.
需要注意的:就是widget的类名.继承的是 AppWidgetProvider
预置apk :
##数据流程加载:
Launcher3 数据加载是从Launcher类的onCreat()方法开始执行.
情况一: 用户离开Launchre页面,采用异步加载
情况二: Launcher 在前台,用户旋转了屏幕,采用同步加载.
两种情况都调用了LauncherModel类的startLoader()方法
startLoader() 函数的核心代码是线程类LoaderTask,该类中有两条路径进行应用数据的加载,其中一个路径就是:
runBindSynchronousPage()//重新加载桌面的应用
另一个路径就是LoaderTask 线程类的Run()方法中.
先是执行loadAndBindWorkspace()方法进行workspace的加载,然后执行loadAndBindAllApps()方法进行所有的app的加载。
所有的数据都都围绕着LauncherModel ,Launcher类实现了callback回调接口.
bindWorkspace的过程如下:
回调接口:
public interface Callbacks {
public boolean setLoadOnResume();
public int getCurrentWorkspaceScreen();
public void startBinding();
public void bindItems(ArrayList shortcuts, int start, int end, boolean forceAnimateIcons);
public void bindScreens(ArrayList orderedScreenIds);
public void bindAddScreens(ArrayList orderedScreenIds);
public void bindFolders(HashMap folders);
public void finishBindingItems(boolean upgradePath);
public void bindAppWidget(LauncherAppWidgetInfo info);
public void bindAllApplications(ArrayList apps);
public void bindAppsAdded(ArrayList newScreens, ArrayList addNotAnimated, ArrayList addAnimated, ArrayList addedApps);
public void bindAppsUpdated(ArrayList apps);
public void bindComponentsRemoved(ArrayList packageNames, ArrayList appInfos, boolean matchPackageNamesOnly);
public void bindPackagesUpdated(ArrayList
1.Launcher3 本身就有具有实现单层的功能:
kk版本要实现单层:
AppsCustomizePagedView.Java中 DISABLE_ALL_APPS== false ,只需修改为 true 即可.
kk2版本要实现单层:
LauncherAppState.java 中 isDisableAllApps() 返回 true 隐藏,返回 false 显示.
2. 屏幕适配 :
Launcher3 中直接是在 DynamicGrid.Java 类中,匹配屏幕的大小;
主要参数含义:
设备名、最小宽度Dps、最小高度Dps、行数、列数、图标大小、图标字体大小、固定热键数目(Hotseat)、固定热键图标大小
DynamicGrid.Java :
有个Layout()方法:中对search bar ,workspace, hotseat ,进行排列,如果我们需要改变大小,就直接在这个类中修改.
设置workspace大小:
#####隐藏Hotseat (xml中注掉控件)
去掉hotseat 相关的类,含有hotseat相关代码.
Launcher.java 直接设置为null
Workspce.java 直接注掉 getUniqueIntents((CellLayout)mLauncher.getHotseat().getLayout(), uniqueIntents, duplicates, false);
LauncherModel.java //会报异常注掉
DynamincGrid.java
Workspace .java 中禁止掉文件夹生成, 在onDrop()方法中处理:
Launcher.java 中禁止workspace长按事件,在onLongClick()方法中处理:
1.隐藏应用图标:
LauncherModel.Java中 loadAllapps()获取到所有应用的集合.,通过包名匹配,然后直接从集合中删除掉不需要创建桌面图标的应用.
2. 隐藏应用图标及应用功能.
直接在Launcher.java中通过代码实现:
让应用可见:
PackageManager.setApplicationEnabledSetting(AUX, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
隐藏应用禁止功能:
PackageManager.setApplicationEnabledSetting(AUX, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
#主题实现