Android Launcher2源码分析

本文详细分析了Android Launcher2的源码,从LauncherModel.startLoader()开始,讲解了如何通过LauncherModel.Callbacks接口回调数据,讨论了在不同状态下如onResume()时如何重新加载。接着,介绍了获取当前屏幕、启动加载、绑定内容项、加载folder、结束加载等关键步骤,包括bindItems、bindFolders、bindAppWidget、bindAppsAdded、bindAppsUpdated和bindAppsRemoved等方法的用途。最后,提到了isAllAppsVisible和bindSearchablesChanged方法在状态变化时的作用,为深入理解整个加载流程提供了指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android   Launcher2源码分析

Android源码程序程序中有一个应用程序入口,官方给出的中文翻译为“启动器”。我们一下统称Launcher.
Launcher源码分析,我们还是从AndroidManifest.xml开始:
<application 
    android: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">
    <activity
        android: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之前,我们需要判断屏幕的大小和屏幕的像素密度,以便创建合适大小的icon
        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);  //用来<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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值