Launcher8.0的Launcher的源码启动过程第三步是创建一系列的Launcher辅助对象,包括UI图标数据的处理类,具体拖拽操作的辅助类,以及为后台运行做准备。
具体的源码部分是这样写的:
1. mOrientation = getResources().getConfiguration().orientation;
2. mSharedPrefs = Utilities.getPrefs(this);
3. mIsSafeModeEnabled = getPackageManager().isSafeMode();
4. mModel = app.setLauncher(this);
5. mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout());
6. mIconCache = app.getIconCache();
7. mAccessibilityDelegate = new LauncherAccessibilityDelegate(this);
8. mDragController = new DragController(this);
9. mAllAppsController = new AllAppsTransitionController(this);
10. mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, mAllAppsController);
11. mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
12. mAppWidgetHost = new LauncherAppWidgetHost(this);
13. if (Utilities.ATLEAST_MARSHMALLOW) {
mAppWidgetHost.addProviderChangeListener(this);
}
14. mAppWidgetHost.startListening();
// If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,
// this also ensures that any synchronous binding below doesn't re-trigger another
// LauncherModel load.
15. mPaused = false;
16. mLauncherView = LayoutInflater.from(this).inflate(R.layout.launcher, null);
每一步都标上序号,我们来一一进行分析:
第一个对象是mOrientation 获取当前手机处于横屏还是竖屏
横竖屏状态下包括布局,操作等都有不同。
第二个对象是SharedPreferences
这里创建的sp对象在Launcher中起着重量级的作用,除了存储桌面布局的行为在在LauncherProvider完成,剩下的信息基本都在SharedPreferences中保存,比如默认屏幕是哪一屏。特别是长按桌面空白的home Settings的选项都是使用SharedPreferences。
第三个对象是获取当前时候处于安全模式下。
设备在日常使用过程中,不可避免的会添加安装第三方应用。但并不是每一个应用都是安全的,对系统无伤害的。由于第三方应用程序,可能会存在一定的兼容性问题,所以在安装软件后可能会出现系统文件报错,甚至手机无法正常开机或者开机后系统程序不停报错的现象。遇到这种情况,若进行恢复出厂设置,手机中的资料是无法进行备份的,但是Android系统中添加了"安全模式"这项功能,有效的避免上述情况同时来排除故障。安全模式下,只能启动系统应用,第三方应用都不会开启或者启动。
第四个对象是LauncherModel
继承BroadcastReceiver,是一个广播接收器,用来接收广播,主要作用是加载数据,处理数据,保存桌面状态,内部类LoaderTask用来初始化桌面。LauncherModel是非常重要的一个类,在启动流程中占据了半壁江山
第五个对象是 ModelWriter
LauncherModel的辅助类,修改储存在数据库里面的数据。
第六个对象是IconCache
此类主要保存图标信息,图标的图片实际都是有各个APK自主提供,而Launcher通过系统接口从手机中读取所有应用的图标将其存在缓存中,避免每次刷新都从手机读取。如果一个应用未能读取到图标,则采用默认图标,也就是安卓小机器人。
第七个对象是LauncherAccessibilityDelegate
拖拽的辅助类,里面的事件有添加,拖动等。
第八个对象DragController
DragController是处理拖拽的重要类,Launcher的顶级布局是DragLayer,所有的拖拽都是在这个布局中完成的,DragController就是DragLayer实现拖拽的辅助类。
第九个对象AllAppsTransitionController
AllAppsController服务于AllAppsContainerView,帮助处理allapp的拖拽等事件。(这个界面是装载所有App的界面)
第十个对象LauncherStateTransitionAnimation
Launcher各个模块之前的切换。比如,从普通模式到拖拽模式,从普通模式到overview模式,从普通模式到allapp模式等等。 LauncherStateTransitionAnimation则是负责完成从一个模式到另一个模式切换的类。
第十一个对象AppWidgetManagerCompat
是辅助AppWidgetManager的一个类,Launcher会从AppWidgetManager中获取一些数据,并且进行一个简单处理后再使用。在实际使用过程中,Launcher发现好多地方都会用到AppWidgetManager的数据,且进行相同的处理。 写好代码的规则有一条,是“代码重构”的相关知识点,其中有种“坏味道”叫做“重复代码”。 简单说,如果同样代码在整个应用中多次出现,则应该把这些代码统一放到一个方法里面。这样代码只出现一次。后面处理方式发生变化,只需在一处修改即可。像对AppWidgetManager处理方式有好几种,每种都好多处用到。则单独创建一个类来存放。
第十二个对象 LauncherAppWidgetHost
创建一个Widget组件。确保Widget可以拖拽。
第十三步添加CallBack
判断当前版本,给Weight添加变化的监听器。
第十四步mAppWidgetHost.startListening()
startListening意味着桌面的widget收到对应app的控制。
第十五步mPaused = false
此参数是用于判断当前Launcher是否处于mPause状态。因为Launcher而有很多后台被动操作,也就是说很有可能Launcher在后台的时候被其他应用调用,这个时候有些行为就需要知道是否处于mPaused