安卓系统是市场占用率最高、用户使用率最多的手机系统。大部分安卓手机厂商在AOSP(Android Open Source Project)的基础上进行二次开发,定制符合自家设备使用的安卓系统。本篇文章记录6.0.1版本launcher3(home程序)的加载过程及launcher.java部分函数分析。

安卓6.0.1版本指定launcher3为默认home程序,作为系统第一个app(由ActivityManagerService的systemReady函数通过Intent(intent.addCategory(Intent.CATEGORY_HOME); 这里注册为Intent.CATEGORY_HOME的Activity)方式打开home程序,这里只是简单介绍不进行详细描述),首先我们看下Launcher3文件夹下的AndroidManifest.xml文件:

  <activityandroid:name="com.android.launcher3.Launcher"android:launchMode="singleTask"android:clearTaskOnLaunch="true"android:stateNotNeeded="true"android:theme="@style/Theme"android:windowSoftInputMode="adjustPan"android:screenOrientation="landscape"android:resumeWhilePausing="true"android:taskAffinity=""android:enabled="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.MONKEY"/></intent-filter></activity>在这段描述中找到了<category android:name="android.intent.category.HOME" />,Launcher.java将作为主Activity进行启动。

下面开始分析Launcher.java的加载过程

找到protected void onCreate(Bundle savedInstanceState)函数:程序的设计者考虑到系统启动过程中可能会不止一次启动launcher3程序(比如launcher3意外退出或别的情况导致),采用Builder模式,用一个内部类去实例化一个对象,避免一个类出现过多构造函数。首先找到if (DEBUG_STRICT_MODE)这条语句,追踪发现DEBUG_STRICT_MODE默认为false,并没有启动严苛模式,继续往下看 if (mLauncherCallbacks != null) {mLauncherCallbacks.preOnCreate();}如果回调方式已经创建,清空回调信息等待再次创建新的实例(当mLauncherCallbacks的OnCreate执行完成后,后续工作由mLauncherCallbacks进行完成,比如关联所有app程序,所有app的响应事件注册等,后续会专门分析launcher3中比较重要的类),继续往下super.onCreate(savedInstanceState);
这个是Builder模式构成的重要部分,由父类或超父类(存在超父类的情况下)创建实例,LauncherAppState.setApplicationContext(getApplicationContext());LauncherAppState app = LauncherAppState.getInstance();LauncherAppState类获取程序环境上下文进行注册服务,调用DeviceProfile实例加载桌面部件,其中包括Hotseat,workspace等;调用LauncherProvider实例监听provider等;调用LauncherModel启动回调等;调用LauncherAccessibilityDelegate增加动作等。 参考下图:


图1

继续往下分析
      mDragController = new DragController(this);
      创建拖动控制器

mInflater = getLayoutInflater();
      布局填充(如果桌面上有空余的部分进行填充)

mStateTransitionAnimation = new LauncherStateTransitionAnimation(this);
     创建icon的动画效果(比如光标停留在app上icon会发生变化、workspace切换页也会有变化)

mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
      获取app部件管理器实例,当前版本判断标准为API21

mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);
      mAppWidgetHost.startListening();
      在AppWidgetHost.startListening()中,AppWidgetHost通过AppWidgetService把AppWidgetHost,HostId等信息注册到AppWidgetService中,启动服务进行监听

setContentView(R.layout.launcher);
      翻译出来的大概意思:从布局资源中设置活动内容。资源将会是
膨胀,将所有顶级视图添加到活动中。
      分析结果:从布局资源中设置活动内容,初始化窗口活动空间。

setupViews();
      进入到SetupViews函数中

mLauncherView = findViewById(R.id.launcher);
      这里调用的是packages/apps/Launcher3/res/下的xml,如果你的桌面设置默认是竖屏将会调用layout-port/launcher.xml,如果桌面默认是横屏调用layout-land/launcher.xml,找到“android:id="@+id/launcher"”修改内部参数即可,这种方法适用所有的xml修改。

mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);
      焦点指示器

mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
      拖动层(如果从xml中设置显示=gone,home主界面变为空白)

mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
     这个可以理解为工作空间,用来放置页视图的cellLayout

mWorkspace.setPageSwitchListener(this);
      绑定页转换监听

mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);
      页指示器(页下面的点,切换页面时可以看到变化)

这几个布局加载方式与mLauncherView = findViewById(R.id.launcher);是同一个xml文件,修改方式也是相同

// Setup the hotseat
      mHotseat = (Hotseat) findViewById(R.id.hotseat);
      if (mHotseat != null) {
        mHotseat.setOnLongClickListener(this);
      }

加载hotseat(抽屉,中间是allapps按钮,点击allapps按钮进入二级界面)
设置hotseat长按键监听,如果不需要可以注释掉,对于allapps按钮进入的二级界面(cellLayout)没有效果

mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);
      描述面板(默认隐藏)

mWidgetsButton = findViewById(R.id.widget_button);
      小部件按钮(在主界面空闲处长按屏幕进入可以看到)
事件函数不再分析,按中文意思理解即可

View wallpaperButton = findViewById(R.id.wallpaper_button);
      壁纸按钮(在主界面空闲处长按屏幕进入可以看到)

View settingsButton = findViewById(R.id.settings_button);
      设置主题按钮(在主界面空闲处长按屏幕进入可以看到)

if (mSearchDropTargetBar != null) {
        mSearchDropTargetBar.setup(this, dragController);
        // 取消上方搜索框
        //mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());
      }

继续回到OnCreate()函数

mDeviceProfile.layout(this);
      在DeviceProfile实例中加载workspace,hotseat,pageIndicator,overviewMode,如果你想完成hotseat放置到主屏幕中间位置、隐藏页指示器等,可以通过修改DeviceProflle文件达到效果(后续文章将详细介绍DeviceProfile文件)

Oncreate、SetViews函数修改的位置大概就这些,后面内容可以参考上面的思路继续分析。

如果想隐藏主界面长按键功能,请在public boolean onLongClick(View v) 中注释掉所有内容,增加return true;即可,大部分事件函数可以用中文意思去理解。

AOSP6.0.1 launcher3入门篇—解析launcher.java文件相关推荐

  1. AOSP6.0.1 launcher3入门篇-解析DeviceProject.java及相关文件

    上一篇文章(AOSP6.0.1 launcher3入门篇-解析launcher.java文件)描述了launcher3的加载过程,本篇文章记录hotseat停靠方向和位置.隐藏页指示器.Folder大 ...

  2. AOSP6.0.1 launcher3入门篇—hotseat相关实现

    在安卓桌面程序的主界面我们可以看到是由QsbSearchBar(上方搜索框).Workspace(页视图空间).pageIndicator(页指示器).hotseat(底部视图空间)四个部分组成,它们 ...

  3. AutoSAR系列讲解(入门篇)5.3-ECUEX文件

    AutoSAR系列讲解(入门篇)5.3-ECUEX文件 ECUEX文件 一.ECUEX简介 二.ECUEX内容涵盖等级 1.等级1:目前普遍状态 2.等级2:进阶状态 3.等级3:终极状态 ECUEX ...

  4. 《从零开始学习ASP.NET MVC 1.0》-开天辟地入门篇

    <从零开始学习ASP.NET MVC 1.0> 文章导航 (一) 开天辟地入门篇 (二) 识别URL的Routing组件 (三) Controller/Action 深入解析与应用实例 ( ...

  5. 〖Python零基础入门篇(55)〗- yaml文件的读取

    订阅 Python全栈白宝书-零基础入门篇 可报销!白嫖入口-请点击我.推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 Python全栈白宝书专栏,免费阶段订阅数量43 ...

  6. 微信小程序开发【从0到1~入门篇】

    目录 1. 微信小程序介绍 1.1 什么是小程序? 1.2  小程序可以干什么? 2. 申请账号 2.1 申请帐号 2.2 测试号申请(我们小程序账号申请完成之后,建议务必要申请一个测试号用来开发) ...

  7. AOSP6.0.1 系统中增加新的category类型与app绑定,并在hotseat容器中加载app

    在launcher3(桌面程序)的hotseat中,可以通过修改dw_phone_hotseat.xml在指定位置加载指定app(仅限于已经指定category类型为APP_xxxx的app或者是系统 ...

  8. Asp.Net MVC2.0 Url 路由入门---实例篇

    本篇主要讲述Routing组件的作用,以及举几个实例来学习Asp.Net MVC2.0 Url路由技术. 接着上一篇开始讲,我们在Global.asax中注册一条路由后,我们的请求是怎么转到相应的Vi ...

  9. HwBinder入门篇-Android10.0 HwBinder通信原理(一)

    摘要:本节主要来讲解Android10.0 HwBinder的通信原理概要 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平 ...

最新文章

  1. PCL点云分割(1)
  2. 每天三分钟玩转Git(已完结)
  3. ADB连接小米手机模拟上下左右滑动实例演示
  4. 来腾讯云开发者实验室 学习.NET
  5. fetch 不是xhr_春招|前端2019应届春招:不是被大厂选,而是选大厂(字节跳动,美团,网易)...
  6. Nginx Learning (1)
  7. .rpt文件内容读取java_Java快速入门(26) 文件和IO操作
  8. Linux工作笔记035---设置连接Linux Centos 超时连接时间_空闲的等待时间 -bash: TMOUT: readonly variable
  9. python中while与else的联姻
  10. hnu 暑期实训之选美比赛
  11. socket编程(十一)
  12. 【ASP.NET 问题】IIS发布网站后出现 “处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误“的解决办法
  13. linux查找符合条件的文件并删除
  14. stardict词典全集
  15. 微型计算机原理考试试卷,微机原理与应用试题库(附答案)
  16. grok调试工具使用
  17. 从host端对Windows虚机进行内存dump和分析
  18. 安装lux:推荐一款网页视频下载工具。并简单使用。(win)
  19. 如何选择APP内测分发平台?五年开发者亲述
  20. TextMesh Pro中文字体的动态生成

热门文章

  1. fail-fast机制(遍历的同时删除List中的对象)
  2. 如此沙雕的代码注释,还是程序员会玩!
  3. 30条架构原则:助你成为大牛架构师
  4. 连载08:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)...
  5. Commons Collections学习笔记(四)
  6. ASP.NET 5 入门 (3) – Logging
  7. Ubuntu 常用工具、指令安装
  8. 技术博客么?开始每天一更
  9. 廖雪峰JS教程--条件判断
  10. Mysql中Innodb大量插入数据时SQL语句的优化