前面两篇文章都是写有关Launcher配置文件的修改,代码方面涉及不多,今天开始进入Launcher代码分析。

我们开机启动Launcher,Launcher是由Activity Manager启动的,而Activity Manager是由system server启动。

原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3157452.html

1、Launcher进程启动过程

可以由下面图看到Launcher进程是如何被创建启动:

Activity Manager通过发送Intend来启动Launcher。

复制代码//Edited by mythou
//http://www.cnblogs.com/mythou/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的程序,只要在程序<intent-filter>里面加入action.MAIN 、

category.HOME、category.DEFAULT就可以。如果出现多个程序都加入这种intent,系统会弹出让你选择

哪个作为启动器。

2、Launcher初始化——LauncherApplication。

Application类,我想大部分做Android应用的朋友都用过,每个Android应用默认都有一个Application类,

你也可以继承Application类,然后加入自己代码。Application是一个全局的应用类,在AndroidManifest.xml

我们也可以找到Application标签。

复制代码//Edited by mythou
//http://www.cnblogs.com/mythou/<applicationandroid:name="com.android.launcher2.LauncherApplication"android:label="@string/application_name"  android:icon="@drawable/ic_launcher_home"android:hardwareAccelerated="@bool/config_hardwareAccelerated"android:largeHeap="@bool/config_largeHeap"android:configChanges="locale"></application>    

Android四大组件的声明都需要放到application标签里面,默认使用的是系统的Application类,如果你在项目

里面重载了它。就需要在标签,name属性下写上你的新的Application类名。Launcher里面就是继承了Application

为LauncherApplication。应用启动的时候首先会加载Application。

我们可以看到Launcher主类Launcher.java的onCreate函数里面,第一个就是获取Application的实例。

LauncherApplication app = ((LauncherApplication)getApplication());

接下来我们看看LauncherApplication里面初始化,LauncherApplication大部分工作就是在初始化完成,剩下都是

一些返回接口。

//Edited by mythou
//http://www.cnblogs.com/mythou/@Overridepublic void onCreate() {super.onCreate();//获取屏幕大小,主要用来区分手机还是平板final int screenSize = getResources().getConfiguration().screenLayout &Configuration.SCREENLAYOUT_SIZE_MASK;sIsScreenLarge = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;//屏幕密度sScreenDensity = getResources().getDisplayMetrics().density;//IconCahe里面保存了界面所有应用图标的绘画需要的数据,这个到时候具体分析再说。//加入这东西的主要原因是为了提高绘画界面的效率mIconCache = new IconCache(this);//数据库加载类,LauncherModel是Launcher里面非常重要的一个类,相当于MVC模式里面的//Model功能,管理数据和初始化数据mModel = new LauncherModel(this, mIconCache);//下面注册了一些监听器,主要包含APK文件更新删除等数据变化的时候接收的通知//接收通知后,主要是用来更新Launcher里面的数据库。因为桌面应用图标数据,只会加载一次IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);filter.addAction(Intent.ACTION_PACKAGE_REMOVED);filter.addAction(Intent.ACTION_PACKAGE_CHANGED);filter.addDataScheme("package");registerReceiver(mModel, filter);filter = new IntentFilter();filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);filter.addAction(Intent.ACTION_LOCALE_CHANGED);filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);registerReceiver(mModel, filter);filter = new IntentFilter();filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);registerReceiver(mModel, filter);filter = new IntentFilter();filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);registerReceiver(mModel, filter);//contentresolver则是用于管理所有程序的contentprovider实例ContentResolver resolver = getContentResolver();//注册内容观察者,监听application数据库变化,回调resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mFavoritesObserver);}

上面是LauncherApplication最主要的工作,初始化整个Launcher的一些关键类,和注册一些监听器。主要都是用

来监听应用的安装更新删除等导致Launcher数据库变化的操作。Launcher数据都是使用contentprovider来提供数据。

其中注册的监听接口是

//Edited by mythou
//http://www.cnblogs.com/mythou/private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) {@Overridepublic void onChange(boolean selfChange) {//重新加载界面数据mModel.startLoader(LauncherApplication.this, false);}};
LauncherSettings.Favorites.CONTENT_URI里面数据发生变化的时候,都会调用mModel.startLoader()接口,
重新加载Launcher的数据。startLoader的具体操作,我后面分析LauncherModel类的时候会分析。这一块涉及
Launcher所有数据加载。剩下的接都是返回初始化时候创建的对象或者获取屏幕密度、获取是否大屏幕。
后面很多处理都需要判断是否是大屏幕,4.0以后手机平板都共用一套系统,导致多了很多处理。

3、Launcher.java初始化

Launcher.java是Launcher里面最主要的类,是一个Activity。启动的第一个组件。既然是Activity,我们要分析它

初始化,毫无疑问,需要找到onCreate()里面分析。把主要一些分析用注释方式写在代码里面,这样比较方便阅读。

//Edited by mythou
//http://www.cnblogs.com/mythou/@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//获取Application 实例LauncherApplication app = ((LauncherApplication)getApplication());//LauncherModel类里面获取Launcher的对象引用mModel = app.setLauncher(this);//获取IconCache,IconCache在Application里面初始化    mIconCache = app.getIconCache();mDragController = new DragController(this);mInflater = getLayoutInflater();mAppWidgetManager = AppWidgetManager.getInstance(this);//监听widget改变,以后在Model里面回调处理的结果mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);mAppWidgetHost.startListening();//这个是设置Launcher的跟踪调试文件,下面很多信息会写到这个文件里面。if (PROFILE_STARTUP) {android.os.Debug.startMethodTracing(Environment.getExternalStorageDirectory() + "/launcher");}//读取本地配置,保存更新配置,清空IconCachecheckForLocaleChange();setContentView(R.layout.launcher);//对所有的UI控件进行加载和配置setupViews();//显示操作提示,第一次启动的时候才会显示showFirstRunWorkspaceCling();//注册监控Launcher数据库变化registerContentObservers();//锁住APP,初始化不能操作。lockAllApps();mSavedState = savedInstanceState;restoreState(mSavedState);// Update customization drawer _after_ restoring the statesif (mAppsCustomizeContent != null) {mAppsCustomizeContent.onPackagesUpdated();}if (PROFILE_STARTUP) {android.os.Debug.stopMethodTracing();}//加载启动数据,所有界面数据(快捷方式、folder、widget、allApp)等在loader里面加载,这部分后面我会详细分析。if (!mRestoring) {mModel.startLoader(this, true);}if (!mModel.isAllAppsLoaded()) {ViewGroup appsCustomizeContentParent = (ViewGroup) mAppsCustomizeContent.getParent();mInflater.inflate(R.layout.apps_customize_progressbar, appsCustomizeContentParent);}// For handling default keysmDefaultKeySsb = new SpannableStringBuilder();Selection.setSelection(mDefaultKeySsb, 0);IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);registerReceiver(mCloseSystemDialogsReceiver, filter);//下面这几个就是Android原生界面上的Market、搜索、声音输入按钮的默认图标显示。boolean searchVisible = false;boolean voiceVisible = false;// If we have a saved version of these external icons, we load them up immediatelyint coi = getCurrentOrientationIndexForGlobalIcons();if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null ||sAppMarketIcon[coi] == null) {updateAppMarketIcon();searchVisible = updateGlobalSearchIcon();voiceVisible = updateVoiceSearchIcon(searchVisible);}if (sGlobalSearchIcon[coi] != null) {updateGlobalSearchIcon(sGlobalSearchIcon[coi]);searchVisible = true;}if (sVoiceSearchIcon[coi] != null) {updateVoiceSearchIcon(sVoiceSearchIcon[coi]);voiceVisible = true;}if (sAppMarketIcon[coi] != null) {updateAppMarketIcon(sAppMarketIcon[coi]);}mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);// On large interfaces, we want the screen to auto-rotate based on the current orientationif (LauncherApplication.isScreenLarge() || Build.TYPE.contentEquals("eng")) {setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);}Log.i(TAG,"------------------------>Launcher init over") ;}

上面就是Launcher.java的初始化,大部分我都写了注释。其实这里最主要的工作是加载界面数据:

mModel.startLoader(this, true); 这块实现是在LauncherModel里面实现的。下一篇文章,我会详细

说明如何加载和获取管理系统里面的APP相关数据。

Android之Launcher分析和修改3——Launcher启动和初始化相关推荐

  1. Android之Launcher分析和修改1——Launcher默认界面配置(default_workspace)

    www.cnblogs.com/mythou/p/3153880.html 最近工作都在修改Launcher,所以打算把分析源码和修改源码的过程记录下来,最近会写一些关于Launcher的分析和修改博 ...

  2. Android Launcher分析和修改1——Launcher默认界面配置(default_workspace)

    最近工作都在修改Launcher,所以打算把分析源码和修改源码的过程记录下来,最近会写一些关于Launcher的分析和修改博文.因为我是修改4.0.3的Launcher,所以后面文章里面的Launch ...

  3. Android之Launcher分析和修改5——HotSeat分析

    今天主要是分析一下Launcher里面的快捷方式导航条--HotSeat,一般我们使用手机底下都会有这个导航条,但是如果4.0的Launcher放到平板电脑里面运行,默认是没有HotSeat的,刚好我 ...

  4. Android Launcher分析和修改5——HotSeat分析

    今天主要是分析一下Launcher里面的快捷方式导航条--HotSeat,一般我们使用手机底下都会有这个导航条,但是如果4.0的Launcher放到平板电脑里面运行,默认是没有HotSeat的,刚好我 ...

  5. android launcher分析和修改10,Android Launcher分析和修改10——HotSeat深入进阶

    前面已经写过Hotseat分析的文章,主要是讲解如何在Launcher里面配置以及修改Hotseat的参数.今天主要是讲解一下如何在Hotseat里面的Item显示名称.这个小问题昨天折腾了半天,最后 ...

  6. Android之Launcher分析和修改4——初始化加载数据

    上面一篇文章说了Launcher是如何被启动的,Launcher启动的过程主要是加载界面数据然后显示出来, 界面数据都是系统APP有关的数据,都是从Launcher的数据库读取,下面我们详细分析Lau ...

  7. Android之Launcher分析和修改2——Icon修改、界面布局调整、壁纸设置

    上一篇文章说了如何修改Android自带Launcher2的默认界面设置(http://www.cnblogs.com/mythou/p/3153880.html). 今天主要是说说Launcher里 ...

  8. android 壁纸改变回调,Android Launcher分析和修改13——实现Launcher编辑模式(1) 壁纸更换...

    已经好久没更新Launcher系列文章,今天不解析源码,讲讲如安在Launcher里面添加桌面设置的功能.今朝很多第三方Launcher或者定制Rom都有简单易用的桌面设置功能.例如小米MIUI的La ...

  9. Android 源码分析(三) Service 启动分析

    //android-8.0.0_r1\frameworks\base\core\java\android\content\Context.java/** * startService是Context的 ...

最新文章

  1. ssas 数据源mysql_BI之SSAS完整实战教程2 -- 开发环境介绍及多维数据集数据源准备...
  2. C语言调用WIN32 API学习之6鼠标与键盘响应
  3. 电子商务应用课程知识整理 第一章-电子商务概述与类型
  4. 简单的UTF8编码生成
  5. php面试宝典1000题,【PHP面试宝典1000题】HTTP中的请求头(深圳小美网络科技)
  6. Android开机设置自启动
  7. 个人生活的量化分析(二):Apple健康数据分析
  8. 基于OpenCV的人脸识别考勤系统——创业计划书
  9. 公司拿到了量化交易模型, 交易员和策略师就可滚蛋了?
  10. 稀疏表示(Sparse representation)原理理解
  11. HTML期末大作业~海贼王大学生HTML网页制作10个页面作品(HTML+CSS+JavaScript)
  12. 8种妙招,公众号实现吸粉引流
  13. h264参数动态调整
  14. 关于C++ 存储类型auto、register、static、extern、mutable
  15. 统筹高效利用时间——《小强升职记(升级版):时间管理故事书》读后感
  16. vue 跳转html页面,vue项目实现页面的跳转
  17. 中关村硬科技孵化器首次合作建科技成果转化创新平台
  18. Mac系统重置MySQL的 root密码
  19. [PMZL]第1卷-误入天庭-01
  20. C++在使用fgetc读取文件时出现方框乱码

热门文章

  1. Apache Member、ALC Beijing 发起人姜宁:一个人走的很快,但是一群人能走得更远
  2. 【Redis】有序集合的交集与并集
  3. 93.7%的程序员!竟然都不知道Redis为什么默认16个数据库?
  4. 巧用Dictionary实现日志数据批量插入
  5. 与您相约.NET Conf China 2020! 新进2位重磅嘉宾
  6. 如何在 Asp.Net Core 实现 Excel 导出功能
  7. 从零开始实现 ASP.NET Core MVC 的插件式开发(九) - 如何启用预编译视图
  8. AA.Dapper升级了
  9. .NET Core开发实战(第8课:配置框架:让服务无缝适应各种环境)--学习笔记
  10. AI Boot Camp 分享之 ML.NET 机器学习指南