Android之Launcher分析和修改3——Launcher启动和初始化

前面两篇文章都是写有关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相关数据。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/293669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

史上最强物理科普!

全世界只有3.14 % 的人关注了爆炸吧知识一沙见世界 一花窥天堂手心握无限 须臾纳永恒杨振宁曾说读上面的四句诗可以感受到物理的美但物理的美不止于此物理还有一种庄严美一种神秘美一种初窥宇宙奥秘的畏惧美物理就是如此的迷人任何语言在它的面前都很贫瘠数学让人摆脱了愚昧而…

mysql 怎么实现随机查询并分页,不重复查询

2019独角兽企业重金招聘Python工程师标准>>> 需求&#xff1a; 企业应用中&#xff0c;一般数据量不是很特别多&#xff0c;同时大多在局域网内&#xff0c;性能不会有问题&#xff0c;一般不会分页处理&#xff0c;随机排序数据一般不会有问题 web网站中&#xf…

主机远程唤醒配置

配置&#xff1a;win10戴尔主机F2进biosbios设置2.系统设置3.以太网设置4.电源管理设置以上设置完成后关机&#xff0c;就可以在远程电脑上打开WakeMeOnLan&#xff0c;然后添加或者搜索需要唤醒的电脑的ip&#xff0c;mac和主机名称&#xff0c;然后就可以唤醒远程主机了查看m…

unix高级编程apue.h问题

2019独角兽企业重金招聘Python工程师标准>>> apue.h头文件为作者自己编写而非系统自带&#xff0c;故需要自行添加&#xff01;第一&#xff1a;打开网站 http://www.apuebook.com/第二&#xff1a;选择合适的版本&#xff08;一共有三个版本&#xff0c;根据书的版…

EIGRP stub SIA

转载于:https://blog.51cto.com/liushuo890/1202399

岛国人气美少女竟然每晚跟 3 个人通宵打麻将?

1 桥本怕不是四川人?▼2 借口总比困难多▼3 突然觉得自己是大厨▼4 连自己都不放过▼5 这就是纹身的烦恼▼6 这又是什么黑暗料理&#xff08;via.坏蛋王师傅&#xff09;▼7 哦吼&#xff0c;是在下输了▼7 哦吼&#xff0c;是在下输了▼你点的每个赞&#xff0c;我都认…

java获取ResultSet长度

2019独角兽企业重金招聘Python工程师标准>>> public class Test { public static void main(String[] args) throws SQLException { Connection conn WLMGlobal.connMgr_stat_instance().getConnection(); Statement stmt conn.createStatement(Result…

浅谈协同过滤推荐算法

在现今的推荐技术和算法中&#xff0c;最被大家广泛认可和采用的就是基于协同过滤的推荐方法。本文将带你深入了解协同过滤的秘密。 1 什么是协同过滤 协同过滤是利用集体智慧的一个典型方法。要理解什么是协同过滤 (Collaborative Filtering, 简称 CF)&#xff0c;首先想一个简…

C# wpf编程CM框架快速入门项目实例

01—事件连接这会自动将控件上的事件关联到ViewModel上的方法。常规约定&#xff1a;<Button x:Name"Save">这将导致按钮的单击事件调用ViewModel上的“Save”方法。简短语法&#xff1a;<Button cal:Message.Attach"Save">这将再次导致按钮的…

我的2021年终总结:初为人父,从头再来

【年终总结】| 作者/Edison最近公司开始一股年终总结浪潮&#xff0c;看着同事们写大作文式的“内卷”总结&#xff0c;我不禁在想我这一年做了什么&#xff0c;那么也就有了这篇总结推文&#xff0c;当然它也是我每年的习惯。传送门&#xff1a;Edison的2020年终总结1也谈2021…

Java 基础【09】你的多继承纳?

Java省略了许多很少用到&#xff0c;缺乏了解&#xff0c;混淆功能的C &#xff0c;在我们的经验中带来更多的悲伤大于收益 。 -----James Gosling James Gosling 这个人大家应该很熟悉&#xff0c;就是最初设计Java 语言的的程序…

开源项目导入eclipse的一般步骤[转]

下载到开源项目后&#xff0c;我们还是希望导入到eclipse中还看&#xff0c;这样要方便点&#xff0c;一般的步骤是这样的 打开源代码目录&#xff0c; 如果看到里面有.calsspath .project文件&#xff0c;那么说明这个项目本来就是eclipse开发的&#xff0c;那么在eclipse中-&…

说说可重复函数(Reentrant) 和线程安全(thread-safe)的区别与联系

在讲可重复函数与线程安全之前先来了解什么是可重复函数和线程安全。可重复函数&#xff1a;在多线程或有异常控制流的情况下,当某个函数运行到中途时,控制流(也就是当前指令序列)就有可能被打断而去执行另一个函数.而"另一个函数"很有可能是它本身.&#xff0c;如果…

Blazor中的无状态组件

声明&#xff1a;本文将RenderFragment称之为组件DOM树或者是组件DOM节点&#xff0c;将*.razor称之为组件。1. 什么是无状态组件如果了解React&#xff0c;那就应该清楚&#xff0c;React中存在着一种组件&#xff0c;它只接收属性&#xff0c;并进行渲染&#xff0c;没有自己…

一次性撤稿70篇!中国学者论文再现大规模撤稿 | 附全名单

全世界只有3.14 % 的人关注了爆炸吧知识2021年1月20日&#xff0c;英国皇家化学学会&#xff08;Royal Society of Chemistry&#xff0c;简称RSC&#xff09;表示&#xff0c;他们正在考虑撤回68篇可能出自“论文工厂”的文章&#xff0c;但当时并没有公布这68篇文章的详情。近…

二叉树前序、中序、后序遍历相互求法

今天来总结下二叉树前序、中序、后序遍历相互求法&#xff0c;即如果知道两个的遍历&#xff0c;如何求第三种遍历方法&#xff0c;比较笨的方法是画出来二叉树&#xff0c;然后根据各种遍历不同的特性来求&#xff0c;也可以编程求出&#xff0c;下面我们分别说明。 首先&…

搭建SVN服务

SVN版本管理工具管理着随时间改变的各种数据像普通文件服务器或者ftp服务器&#xff0c;但是&#xff0c;SVN会备份并记录每个文件每一次的修改记录Subversion官网&#xff1a;http://subversion.tigris.org/http://subversion.apache.org/svn客户端&#xff1a; http://tortoi…