自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(77)
  • 收藏
  • 关注

原创 【源码剖析2】framework 源码 6——UserController之多用户的切换(下)

本章直接从UserController的方法moveUserToForeground讲起,就分析多用户切换的时候,如何启动的新用户里面的那个应用。此方法进行了一个判断,该判断最终走向两个分支方法:startHomeActivity和stackSupervisorResumeFocusedStackTopActivity。什么意思呢,就是说切换用户的是,启动用户有两种情况:前者...

2019-07-19 21:46:34 588 1

原创 【源码剖析2】framework 源码 5——UserController之多用户的切换流程(中)

上一章讲解了,第三方app要切换用户ActivityManagerService的SwtichUser方法最终走到切换用户的最关键方法: UserController里面的startUser方法。前面叫做切换用户,而当前这一步这叫做启动新用户。其实切换到新用户就是启动新用户的过程。本章将详细讲解startUser方法。boolean startUser(fina...

2019-07-15 22:08:04 917 2

原创 【源码剖析2】framework 源码 4——UserController之多用户的切换流程(上)

上文提到创建用户之后,需要通过切换用户来抵达用户。细心的朋友会发现标题从UserManagerService变成了UserController。这是因为切换的代码主要在UserController实现,有意思的是,切换的入口也不是在UserManager而是在ActivityManagerService。ActivityManager.getService().switchUser(userI...

2019-07-05 22:07:07 1881

原创 【源码剖析2】framework 源码 3——UserManagerService之多用户的创建代码详解

上文提到创建用户的方法:核心代码是createUserInternalUnchecked在此方法中要完成一个用户的创建。首先是通过flag区分需要创建用户的类型,然后不同类型在信息的使用上会有不同差别。 总的来说,创建时兼顾了各种类型的user,并且给新用户提供userId和UserInfo两个重要参数。需要注意的是,创建用户并不会使用户显示出来。要显示用户是通过多用户切换功能...

2019-07-03 21:21:55 735

原创 【源码剖析2】framework 源码 2——UserManagerService之多用户的创建createUser详解

上文提到创建用户的方法:UserManagermUserManager= (UserManager) context.getSystemService(Context.USER_SERVICE);UserInfonewUserInfo= mUserManager.createUser(“用户名”, 0);入口代码是UserManagerService中的createUs...

2019-06-25 22:31:53 1442

原创 【源码剖析2】framework 源码 1——UserManagerService之多用户的创建、删除和切换的简介

半年以前2018年11月,我从终端系统应用开发(Launcher)换到了终端framework的开发,在学习新知识的过程中,不愿意对写不成熟的知识来无人子弟,因此,有半年未更新。现在重新开始讲讲关于framework的知识。多用户的核心是UserManagerService,顾名思义整个用户是由它来管理,以userManagerService为核心,围绕着,UserManager、U...

2019-06-21 22:26:29 959 2

原创 【源码剖析】Launcher 8.0 源码 31---用户操作(8)拖拽模式之draglayer和结束语

在完整的讲解了拖拽流程之后,或许还有一个疑问:dragOver是被谁调用的?点击进入click,然后处理完成,长按进入onlongclick处理完成,这两者都是view的接口。那么,drag的过程中,需要一直读取手指的位置,这些操作自然也是view的接口View.OnDragListener。Launcher8.0有一个类叫做PinItemDragListener专门用来处理drag相关的...

2018-09-20 13:53:12 447 3

原创 【源码剖析】Launcher 8.0 源码 30---用户操作(7)拖拽模式之图标放到桌面上

讲解了各类特殊的操作,不能忘记最常见的操作,把图标放到桌面上。workspace的droptarget,首先是onDragEnter,从folder或者buttonTargetBar进入workspace。比如先从workspace拖动到buttonTargetBar,然后再回到workspace里。最后回到workspace里面的时候,就会触发workspace的onDragEnter。其中...

2018-09-20 13:52:32 662 3

原创 【源码剖析】Launcher 8.0 源码 29---用户操作(6)拖拽模式之拖拽的特殊操作

人生三大问题,从哪里来?到哪里去?要干什么?如果说dragListener主要关注的是从哪里来。那么DropTarget 则回答了到哪里去。 应用可能拖到想放下的地方,可能拖到删除的选项,可能拖到了没有空位的页面。不同的结果由DropTarget 以及相关的一些类和对象来处理。 DropTarget 一个接口,其源码如下: public interface DropTa...

2018-09-20 13:52:02 432

原创 【源码剖析】Launcher 8.0 源码 28---用户操作(5)拖拽模式之拖拽的开始和结束

开始拖拽应用后,除了workspace进入springload之外,其他模块也会进入springload,主要是folder、allapp、widget这三个模块。而后面三个模块最终也进入workspace的拖拽。当进入springload模式之后,就要关注到拖拽的任务,在前文中有两个拖拽的核心类没有展开讲,现在则开始补上之前很重要而没有细说的DragListener 和DropTarget。这两...

2018-09-20 13:51:30 632

原创 【源码剖析】Launcher 8.0 源码 27---用户操作(4)拖拽模式之springload(下)

除了workspace进入springload之外,其他模块也会进入springload,主要是folder、allapp、widget,这三个模块 先看folder,从onlongclick开始。public boolean onLongClick(View v) {    if (!mLauncher.isDraggingEnabled()) return true;   ...

2018-09-20 13:50:39 551

原创 【源码剖析】Launcher 8.0 源码 26---用户操作(3)拖拽模式之springload

接下来是第三种状态,springloader模式,也是drag模式。 到此刻用户的操作有3中,点击,滑动,长按。点击是触发onclick,滑动是GroupView自带方法,而长按一种是进入overview或allapp模式,另外一种就是接下来学习的drag模式。 之前分析,drag模式的起点有 workspace、folder、allapp、widget、overview。...

2018-09-20 13:50:04 584 2

原创 【源码剖析】Launcher 8.0 源码 25---用户操作(2)模式切换

 模式就是界面,除普通模式外,Launcher还有两个特殊模式,分别是overView模式和Springloader模式。此处采用状态模式这种设计模式,共有三个状态。 overView模式是长按桌面空白处,出现特殊功能,比如设置壁纸,添加widget,特殊设置(横屏开关,负一屏开关等),设置主屏幕(点击home键自动移动到的cellLayout),删除屏幕等。 Springload...

2018-09-20 13:49:33 617

原创 【源码剖析】Launcher 8.0 源码 24---用户操作(1)点击

学习了启动流程,我们知道了Launcher的显示流程,完成启动流程后,就行程开机可见的Launcher桌面了,接下来则是看用户能够怎样操作所见的Launcher。 操作的内容包括,打开应用,调整布局,删除应用,创建文件夹,添加小部件等等。比如调整布局,包括拖拽图标,图标自动排列,滑动翻页等等 Launcher翻译成中文是启动器,就像手机的核心是通话,Launcher的核心用是打...

2018-09-20 13:48:45 716

原创 【源码剖析】Launcher 8.0 源码 (23) --- Launcher 启动流程 第七步(结束)

第六步完成后,Launcher基本就结束了。Launcher8.0启动流程的第七步 横屏和callback等最后的善后工作 接下来是第七步:横屏和callback。  if (!mRotationEnabled) {        mRotationEnabled = Utilities.isAllowRotationPrefEnabled(getApplicationCon...

2018-07-30 09:34:25 466

原创 【源码剖析】Launcher 8.0 源码 (22) --- Launcher 启动流程 第六步之loadAllApps第2小步recycleVIew显示

Launcher8.0启动流程的第六步在workspace图标显示完成就开始准备allapp的显示。因为allapp需要点击或滑动allappButton才能打开,所以显示在workspace之后。Loadallapp是从系统获取所有的应用,然后将其显示到allapp里面。 继续bindallapp,完成了排序后,需要统计sectionname也就首字母,是用于allapp右侧的快捷栏。...

2018-07-30 09:34:15 492

原创 【源码剖析】Launcher 8.0 源码 (21) --- Launcher 启动流程 第六步之loadAllApps第1小步从系统读取数据

Launcher8.0启动流程的第六步在workspace图标显示完成就开始准备allapp的显示。因为allapp需要点击或滑动allappButton才能打开,所以显示在workspace之后。Loadallapp是从系统获取所有的应用,然后将其显示到allapp里面。 private void loadAllApps() {//仍然回调Launcher的方法,所以先获取Laun...

2018-07-26 11:36:59 762

原创 【源码剖析】Launcher 8.0 源码 (20) --- Launcher 启动流程 第六步之BindWorkspace 第2小步添加图标

Launcher8.0启动流程的第六步startLoader的bindWorkspace将sBgDataModel中的图标放到桌面上。 放置的时候为了提高用户体验,优先放置当前屏幕的图标和widget,然后再放其他屏幕的图标,这样用户能更快的看到图标显示完成。 在创建完屏幕后,添加桌面的图标进入bindWorkspaceItems()方法//绑定图标是回调Launcher的对应方法,...

2018-07-26 11:36:26 639

原创 【源码剖析】Launcher 8.0 源码 (19) --- Launcher 启动流程 第六步之BindWorkspace 第1小步创建屏幕

Launcher8.0启动流程的第六步startLoader的第一步Loadworkspace完成,接着是第二步bindworkspace。 这一步将sBgDataModel中的图标放到桌面上。 放置的时候需要先创建屏幕而后才能将图标放到屏幕里。 源码如下:private void bindWorkspace(int synchronizeBindPage) {    final l...

2018-07-26 11:35:51 532

原创 【源码剖析】Launcher 8.0 源码 (18) --- Launcher 启动流程 第六步之LoadWorkspace 第2小步(2)根据不同的图标类型放入不同的缓存中

Launcher8.0启动流程的第六步中loadworkspace的第2小步的做好准备后,已经锁定对于的数据库,并且开启循环读取模式,接着就是依次将读取的内容放入缓存中。 直接上源码,由于源码太长,无法分隔成多个小步来简化记忆。分析以注释的形式放在源码中间。            boolean allowMissingTarget = false;            swi...

2018-07-26 11:35:11 903

原创 【源码剖析】Launcher 8.0 源码 (17) --- Launcher 启动流程 第六步之LoadWorkspace 第2小步(1)图标各参数类型准备

Launcher8.0启动流程的第六步中loadworkspace的第1小步的结束是有一个带布局的数据库,而launcher布局不是直接从数据库放到桌面上,而是从数据库读取到BgDataModel的缓存中在放到桌面上。 如果不是第一次开机,那么数据库里面存储着布局的信息,第一小步是不做的,直接做第二小步获取数据库的信息。 第二小步就是获取数据库信息。将数据库的信息存入缓存中,即多个...

2018-07-26 11:34:29 443

原创 【源码剖析】Launcher 8.0 源码 (16) --- Launcher 启动流程 第六步之LoadWorkspace 第1小步(4)解析布局xml文件

Launcher8.0启动流程的第六步中loadworkspace的第1小步是获取数据库,在没有布局时,需要读取手机上的布局xml文件,通过第三个操作我们创建了新的数据库并选取了xml文件那么如何解析该xml文件呢? 答案是loadFavorites方法该方法把loader对应的xml布局文件放到数据库中。源码如下:int loadFavorites(SQLiteDatabas...

2018-07-26 11:33:40 458

原创 【源码剖析】Launcher 8.0 源码 (15) --- Launcher 启动流程 第六步之LoadWorkspace 第1小步(3)读取布局xml文件

Launcher8.0启动流程的第六步中loadworkspace的第1小步是获取数据库,在没有布局时,需要读取手机上的布局xml文件,通过第二个操作知道了到底选取哪里的xml文件,但是,手机的行列数参数是Launcher根据手机本身通过启动流程第一步获取的,在运行之前不知道,那么如何选择行列数正确的xml文件呢? 这里就涉及到一个重要的类 AutoInstallsLayout 和该类的一...

2018-07-26 11:32:12 601

原创 【源码剖析】Launcher 8.0 源码 (14) --- Launcher 启动流程 第六步之LoadWorkspace 第1小步(2)寻找布局xml的范围

Launcher8.0启动流程的第六步中loadworkspace的第1小步是获取数据库,首先完成第一个操作,判断有没有现成的数据库,如果没有现成数据库,则创建一个新的数据库,并且从手机中读取相应的布局。也就是第1小步的第二个操作,寻找布局文件的范围。loadDefaultFavoritesIfNecessary其源码如下:synchronized private void loadD...

2018-07-26 11:29:03 630

原创 【源码剖析】Launcher 8.0 源码 (13) --- Launcher 启动流程 第六步之LoadWorkspace 第1小步(1)call LauncherProvider

Launcher8.0启动流程的第六步生成布局,Launcher启动流程中最重要,最复杂,也是网上各种关于Launcher讲解的最浓墨淡彩描述的部分。其中的一部分loadworkspace就非常复杂涉及很多代码。从逻辑Loadworkspace一共可以分两小步,第1小步是获取数据库,如果有数据库则直接进入第2小步,如果数据库为空则从xml布局文件生成数据库。第2小步,从数据库读取信息存放到sB...

2018-07-26 11:25:44 1745

原创 【源码剖析】Launcher 8.0 源码 (12) --- Launcher 启动流程 第六步之简述

Launcher8.0启动流程的第六步生成布局,Launcher启动流程中最重要,最复杂,也是网上各种关于Launcher讲解的最浓墨淡彩描述的部分。第六步onCreate中源码如下: if (!mModel.startLoader(currentScreen)) {        mDragLayer.setAlpha(0);    } else {        mWorkspa...

2018-07-26 11:24:55 638

原创 【源码剖析】Launcher 8.0 源码 (11) --- Launcher 启动流程 第五步之细化布局具体参数

Launcher8.0启动流程的第五步,UI子模块的细节规划,各个模块的大小,真正的尺寸等等。这一步是采用第一步获取的方案,把第四步的模块细节进行完成。 在onCreate方法中,其源码如下: mDeviceProfile.layout(this, false /* notifyListeners */);    mExtractedColors = new ExtractedC...

2018-07-24 19:29:43 515

原创 【源码剖析】Launcher 8.0 源码 (10) --- Launcher 启动流程 第四步之第3小步桌面UI模块创建

Launcher8.0启动流程的第四步,第3小步同样服务于第四步setupView,创建UI的各个模块,各个模块在Launcher.xml作为一个整体存在。所以将各模块创建好,整体也自然而然的创建好了。 第三小步源码如下:    mWorkspace.setHapticFeedbackEnabled(false);    mWorkspace.setOnLongClickListe...

2018-07-24 19:29:06 492

原创 【源码剖析】Launcher 8.0 源码 (9) --- Launcher 启动流程 第四步之第2小步OverViewPanel及其三个按钮

Launcher8.0启动流程的第四步,第2小步。定义OverViewPanel,关于OverViewPanel的布局整体在res里面以xml文件形式存在,而对于其细节层面,比如点击之后有什么用则再java层详细定义,而第2小步则是定义OverViewPanel三个按钮的功能。 在setupView的完整源码,以setupOverviewPanel方法为分界线,分为3小步。说明setupO...

2018-07-24 19:28:33 965

原创 【源码剖析】Launcher 8.0 源码 (8) --- Launcher 启动流程 第四步之桌面布局简述和第1小步部分模块创建

Launcher8.0启动流程的第四步,生成桌面分布局。将UI布局的各个模块,进行基本创建,定义和绑定操作事件等。 在oncreate里面就是一个方法:setupViews()主要涉及的模块是DragLayer、Workspace、Qsb、Hotseat、OverviewPanel、AppsView、WidgetsView、DropTargetBar。 这几乎涵盖了桌面能够显示的所有U...

2018-07-24 19:27:56 647

原创 【源码剖析】Launcher 8.0 源码 (7) --- Launcher 启动流程 第三步之统一创建对象

Launcher8.0启动流程的第三步,统一创建对象。创建这些对象主要为后面定义UI各个模块,读取绑定图标操作,以及操作事件和后台运行等做准备。 之前创建LauncherAppState的时候,为了很好的得到参数,已经创建了很多对象,其中有很多对象是非常重要的,不仅在LauncherAppState中使用,也在Launcher中使用,所以,需要将之前创建过的类获取到Launcher中,除此...

2018-07-24 19:27:18 699

原创 【源码剖析】Launcher 8.0 源码 (6) --- Launcher 启动流程 第二步之启动流程中的分屏简介

启动流程第二步,对于分屏状态的判断。分屏状态是在当前手机有两个及以上的支持分屏功能的应用在前后台运行的时候长按recent按钮,而出现手机屏幕一分为二,可以同时有两个应用在前台运行和显示的功能。 第二步源码如下:if (isInMultiWindowModeCompat()) {    Display display = getWindowManager().getDefaultDi...

2018-07-24 19:26:12 626

原创 【源码剖析】Launcher 8.0 源码 (5) --- Launcher 启动流程 第一步(4)之LauncherAppState剩余创建流程

完成了最重要(对启动流程而言)的布局获取,剩下还需要进行Launcher的准备工作。 首先是mIconCache和WidgetPreviewLoader的构造。LauncherAppState构造器所创建第二个对象是IconCache,其代码如下:在IconCache类是存放图标中图片的信息。其中创建IconDB对象 public IconCache(Context con...

2018-07-23 18:42:13 848

原创 【源码剖析】Launcher 8.0 源码 (4) --- Launcher 启动流程 第一步(3)之获取布局参数(续)

第一步重点是找准模型,而后还是更多细节上面的工作,首先,对于真正的桌面,我们需要提供两套显示方案,分别是横屏方案和竖屏方案。两套方案的重点区别是长宽的区别。竖屏是上下距离大,而左右距离小。  而横屏则是左右距离大,上下距离小。于是通过将距离大的放在作为宽度还是作为长度就可以设定好布局。其代码如下:    int smallSide = Math.min(realSize.x, r...

2018-07-23 18:41:34 801

原创 【源码剖析】Launcher 8.0 源码 (3) --- Launcher 启动流程 第一步(2)之获取硬件参数,确定布局参数

获取桌面布局参数,是在InvariantDeviceProfile进行,而后在DeviceProfile中完成参数的规划。参数布局是采用profile比较来完成。mInvariantDeviceProfile = new InvariantDeviceProfile(mContext);LauncherAppState构造器里的第一行代码,其源码如下: InvariantDevic...

2018-07-23 18:40:27 734

原创 【源码剖析】Launcher 8.0 源码 (2) --- Launcher 启动流程 第一步(1)之LauncherAppState 对象创建简述

从综述将启动流程拆分成7步,其中第一步,重点是通过手机的硬件来获取信息。关于第一步在oncreate中的源码如下:@Overrideprotected void onCreate(Bundle savedInstanceState) {if (mLauncherCallbacks != null) {    mLauncherCallbacks.preOnCreate();}s...

2018-07-23 18:38:41 1255

原创 【源码剖析】Launcher 8.0 源码 (1) --- Launcher 启动流程 综述

现在网上关于Launcher启动流程的源码分析流传最多的是google Launcher2.0的启动流程。截止2018年5月,google Launcher已经到了8.0版本。 经对比,8.0和2.0的启动流程大同小异,整体流程依然保留了2.0的结构特征,以LauncherAppState开始获取手机各项参数,从Launcher到LauncherModel再由LauncherModel到L...

2018-07-23 18:37:12 2350

原创 【笨鸟先飞】Java重新学习日记21--设计模式之模板模式和状态模式简介

设计模式是面向对象设计的精华,而面向对象终归于继承、封装和多态。我本次学习设计模式重在体会面向对象设计的思维方式,同时知晓该设计模式的应用场景,当后来遇到相似场景,可以直接借鉴该设计模式。 之前学习了策略模式,策略模式的核心是有一个父类的大概实现,以及继承自父类的具体算法实现。 就以继承为主的设计模式,有一个经典模式叫做模板模式。顾名思义,创建一个父类,让别人去写子类,在子类中写出他们真正想要的。...

2018-02-09 14:34:28 302

原创 【学以致用】android功能实现9---Launcher之AS中,在Launcher源码中增加google负一屏的实现方法

负一屏是相对于正常屏幕而言,正常屏幕是指桌面上用户用于摆放图标(也可以编辑图标位置)的屏幕,根据用户喜欢可以有一个或多个屏幕。在一些手机当中,包括苹果和安卓,在正常屏幕的最左边一屏,我们再往左滑,会出现一个特殊的屏幕。这个屏幕往往会提供:语音搜索?常用应用?天气预报? 都有可能提供,也可以提供其他内容。 Android的负一屏的实现主流有两种方式:其一,Launcher自行开发,通过Launche...

2018-02-09 14:33:45 5797 18

原创 【学以致用】android功能实现8---Android Studio 的UiAutomator 2.0的测试覆盖率验证

之前研究了如果使用Uiautomator 2.0来自动化模拟人的手动测试,来检测程序的基本功能是否完整。然而,根据经验来检测功能,是人为设定哪些功能是我们需要关注的,认为设定的真的测试完整了吗?这个测试究竟对程序验证到了什么程度?这就需要代码覆盖率来完成。 首先,人为设定哪些需要检测是可行的,也是可信的。程序是程序员设计的,这个程序有什么目的,需要完成什么功能,程序员是知道的,所以我们可以

2018-02-02 14:20:33 981

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除