大叔的愤怒,你驾驭不了

Android Launcher2源码分析

Android源码程序程序中有一个应用程序入口,官方给出的中文翻译为“启动器”。我们一下统称Launcher.

Launcher源码分析,我们还是从AndroidManifest.xml开始:

<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"><activityandroid:name="com.android.launcher2.Launcher"…><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>…</application>其他,我们姑且也不管,有三点我们必须说一下:

一、android:hardwareAccelerated="@bool/config_hardwareAccelerated"

指定了整个应用程序是启用硬件加速的,这样整个应用程序的运行速度会更快。

二、

android:largeHeap="@bool/config_largeHeap"指定了应用程序使用了大的堆内存,,能在一定程度上避免,对内存out of memory错误的出现。

三、

<category android:name="android.intent.category.HOME" />这个申明,相当于告诉系统这是桌面Activity。如果你希望开发自己的桌面应用。这个申明是必须的

通过这三点的设置,我们大概知道了桌面的核心。

那么,接下来我们从LauncherApplication(com/android/launcher2/LauncherApplication.java)应用程序开始分析

public void onCreate() {super.onCreate();// 在创建icon cache之前,我们需要判断屏幕的大小和屏幕的像素密度,以便创建合适大小的iconfinal 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); //用来<span style="color: rgb(51, 51, 51); font-family: 宋体; font-size: 14px; line-height: 28px; text-indent: 28px; background-color: rgb(248, 248, 248);">设置了应用程序的图标的cache</span>mModel = new LauncherModel(this, mIconCache); //<span style="color: rgb(51, 51, 51); font-family: 宋体; font-size: 14px; line-height: 28px; text-indent: 28px; background-color: rgb(248, 248, 248);">LauncherModel主要用于加载桌面的图标、插件和文件夹,同时LaucherModel是一个广播接收器,在程序包发生改变、区域、或者配置文件发生改变时,都会发送广播给LaucherModel,LaucherModel会根据不同的广播来做相应加载操作</span>// 注册广播接收器IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);……registerReceiver(mModel, filter);//注册ContentObserver,监听LauncherSettings.Favorites.CONTENT_URI数据的变化ContentResolver resolver = getContentResolver();resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true,mFavoritesObserver);}查看IconCache(com.android.launcher2.IconCache.java)我们很容易发现,这是一个应用程序图标(icon)缓冲生成器。正如我们刚才所说的,我们知道LauncherModel主要用于加载桌面的图标(icon)、插件(AppWidge)和文件夹(Floder) 和Shortcut。

在LauncherModel(com.android.launcher2.LauncherModel.java)中

public class LauncherModel extends BroadcastReceiver {public interface Callbacks {public boolean setLoadOnResume();public int getCurrentWorkspaceScreen();public void startBinding();public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end);public void bindFolders(HashMap<Long,FolderInfo> folders);public void finishBindingItems();public void bindAppWidget(LauncherAppWidgetInfo info);public void bindAllApplications(ArrayList<ApplicationInfo> apps);public void bindAppsAdded(ArrayList<ApplicationInfo> apps);public void bindAppsUpdated(ArrayList<ApplicationInfo> apps);public void bindAppsRemoved(ArrayList<ApplicationInfo> apps, boolean permanent);public void bindPackagesUpdated();public boolean isAllAppsVisible();public void bindSearchablesChanged();} }很明显

LauncherModel.startLoader(),开始加载的工作。launcherModel中加载好的内容会通过

LauncherModel.Callbacks接口的回调函数将数据传给需要的组件

setLoadOnResume() 由于Launcher继承自Activity,因此Launcher可能会处于paused状态(onPause()被调用),

则有可能在这段时间内资源可能发生了改变,如应用被删除或新应用安装,因此需要在onResume()中调用此方法进行重新加载。

getCurrentWorkspace() 获取当前屏幕的序号

startBinding() 通知Launcher加载开始,并更新Workspace上的shortcuts

bindItems(ArrayList<ItemInfo> shortcuts, int start, int end) 加载一批内容项到Workspace,加载的内容项包括,

Application、shortcut、folder。

bindFolders(HashMap<Long, FolderInfo> folders) 加载folder的内容

finishBindingItems()通知Launcher加载结束。

bindAppWidget(LauncherAppWidgetInfo item) 加载AppWidget到Workspace

bindAllApplications(final ArrayList<ApplicationInfo> apps)在All Apps页加载所有应用的Icon

bindAppsAdded(ArrayList<ApplicationInfo> apps)通知Launcher一个新的应用被安装,并加载这个应用

bindAppsUpdated(ArrayList<ApplicationInfo> apps)通知Launcher一个应用发生了更新

bindAppsRemoved(ArrayList<ApplicationInfo> apps, boolean permanent) 通知Launcher一个应用被删除了

bindPackagesUpdated() 通知Launcher多个应用发生了更新

isAllAppsVisible()用于在加载的过程中记录当前Launcher的状态,返回true则当前显示的All Apps

bindSearchablesChanged()当搜索/删除框状态发生改变时调用

了解了每个方法的作用之后,就可以开始进一步的分析了。

了解了大概过程,下一步。我们走到Launcher(com.android.launcher2.Launcher.java)

醒来第一眼看见的是他,然后倒头继续睡。这就是我想要的幸福。

大叔的愤怒,你驾驭不了

相关文章:

你感兴趣的文章:

标签云: