分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
转自:
http://blog.csdn.net/wdaming1986/article/details/7585649
http://blog.csdn.net/wdaming1986/article/details/7671318
最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程。Launcher其实是贯彻于手机的整个系统的,时时刻刻都在运行,要是Launcher不运行了,手机就得黑屏了。Launcher的LauncherMode=singletask,所以说不管Launcher启动了哪个应用,总有个Launcher的实例在堆栈中,并且位于栈底。点击Home键进入到Launcher,上篇Android的全局键(home键/长按耳机键)详解【android源码解析八】中有详细的介绍。大致思路其实就是启动launcher的时候,新启动一个task。大致先说这么多,先看截图:
大明原创,转载请标明出处:http://blog.csdn.net/wdaming1986/article/details/7585649
图(1)
上图是4.0的Launcher界面,下面我们分步来解析一下Launcher的启动过程。
Step 0:首先要给大家介绍一下Launcher的数据库,这个数据库中存放着待机界面的图标,主屏底部的应用程序图标和桌面folder中各应用程序的图标,ICS4.0的folder中只能放应用程序的快捷方式,shortcut不能放到这个folder中,先看截图:
图(2)
说说各字段的含义:
title:表示桌面应用程序的名字,有的title为空,表示是widget的快捷方式;
intent:表示启动这个图标的intent放到数据库中,当click的时候就会调用这个字段,启动相应的应用程序;
container:表示应用程序的容器,folder的容器为整数,-100:表示在桌面的程序,-101:表示是主屏底部的程序;
screen:表示在第几个屏,folder的screen都是0, container=-101的为0,1,3,4;2为allapp的按钮;
cellX:表示在屏幕X轴的位置,(0,1,2,3),左上角为0点,往右依次增加;
cellY:表示在屏幕Y轴的位置,(0,1,2,3),左上角为0点,往下依次增加;
spallX:表示占X轴几个格;
spallY:表示占Y轴几个格;
itemType:应用程序用0表示,shortcut用1表示,folder用2表示,widget用4表示;
appWidgetId:-1表示不是widget,数字大于0表示才是widget;
isShortCut:值为0表示不是应用程序的ShortCut,值为1表示是应用程序的ShortCut;
iconType:值为0表示图标的名字被定义为包名的资源id,值为1表示图标用bitmap保存;
icon:表示应用程序的图标,二进制的;显示为一张图片;
说明:folder中的应用快捷方式绑定folder---->是用container的值绑定folder的id的;
详细的讲解请参考LauncherSettings.java这个类,有数据库字段的详细讲解;
手机是在第一次烧机完成后,数据库的值还没有,这时候launcher解析default_workspace.xml把这个值存到数据库中;所以说想定制什么样的开机桌面就在default_workspace.xml中做相应的配置,具体参照我前面的博客:
Android中源码Launcher主屏幕程序排列详解【安卓Launcher进化一】中有详细的介绍:
i f (!convertDatabase(db)) {
// Populate favorites table with initial favorites
loadFavorites(db, R.xml.default_workspace);
}
Step 1:开机后先启动LauncherApplication.java这个类的onCreate()方法,下面看代码:
- @Override
- public void onCreate() {
- super.onCreate();
- // set sIsScreenXLarge and sScreenDensity *before* creating icon cache
- // 在创建图标缓存之前先设置sIsScreenXLarge和屏幕设备的分辨率
- 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;
- // 实例化图标缓存区的对象
- mIconCache = new IconCache(this);
- // 实例化一个LauncherModel对象,这个类是保存Launcher的内存启动状态,更新Launcher的数据库的作用
- mModel = new LauncherModel(this, mIconCache);
- // Register intent receivers
- // 注册监听,应用package增加,删除,改变的监听。
- 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();
- // 注册application是否可用,语言改变,方向改变的监听。4.0支持横竖屏
- 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);
- // Register for changes to the favorites
- // 注册favorites应用程序数据库改变的监听
- ContentResolver resolver = getContentResolver();
- resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI,true,
- mFavoritesObserver);
- }
@Override public void onCreate() { super.onCreate(); // set sIsScreenXLarge and sScreenDensity *before* creating icon cache // 在创建图标缓存之前先设置sIsScreenXLarge和屏幕设备的分辨率 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; // 实例化图标缓存区的对象 mIconCache = new IconCache(this); // 实例化一个LauncherModel对象,这个类是保存Launcher的内存启动状态,更新Launcher的数据库的作用 mModel = new LauncherModel(this, mIconCache); // Register intent receivers // 注册监听,应用package增加,删除,改变的监听。 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(); // 注册application是否可用,语言改变,方向改变的监听。4.0支持横竖屏 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); // Register for changes to the favorites // 注册favorites应用程序数据库改变的监听 ContentResolver resolver = getContentResolver(); resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mFavoritesObserver); }
Step 2:在LauncherApplication.java中onTerminate()的方法,解除监听的绑定;
Step 3:Step1中的数据库mFavoritesObserver监听内部类如下: