Launcher3源码分析(LauncherModel加载数据)

LauncherModel继承BroadcastReceiver,显然是一个广播接收者。在上一篇Launcher的启动中讲到桌面数据的加载工作是在LauncherModel中执行的,那么它是如何加载数据的呢?下面将分析Launcher和LauncherModel的通讯方式以及LauncherModel加载桌面数据的过程。

首先分析的是Launcher和LauncherModel的通讯方式:

(1)LauncherModel.Callback回调接口:LauncherModel通过接口输送已经加载完成的数据给Launcher。

//在Launcher.java中持有LauncherModel对象
mModel = app.setLauncher(this);

继续分析setLauncher(Launcher launcher)方法

//返回LauncherModel
LauncherModel setLauncher(Launcher launcher) {

        getLauncherProvider().setLauncherProviderChangeListener(launcher);
        mModel.initialize(launcher);
        mAccessibilityDelegate = ((launcher != null) && Utilities.isLmpOrAbove()) ?
            new LauncherAccessibilityDelegate(launcher) : null;
        return mModel;
    }

以上方法引用了此LauncherModel中的initialize(Callbacks callbacks);方法。且到LauncherModel中分析

public void initialize(Callbacks callbacks) {

        synchronized (mLock) {
            // Disconnect any of the callbacks and drawables associated with ItemInfos on the
            // workspace to prevent leaking Launcher activities on orientation change.
            unbindItemInfosAndClearQueuedBindRunnables();
            mCallbacks = new WeakReference<Callbacks>(callbacks);
        }
    }

发现传入的参数是Callbacks对象,而Launcher实现了LauncherModel.Callbacks接口,显然LauncherModel和Launcher就建立了联系。

从而完成了Launcher在LauncherModel中注册接口,将接口实现的引用注册到LauncherModel中,并且返回已经完成初始化的LauncherModel的引用。LauncherModel的所有操作结果都会通过callbacks中定义的各个回调接口中的方法通知给Launcher,并由Launcher分发给不同的桌面组件或者Launcher自身。

LauncherModel提供的Callbacks接口:

public interface Callbacks {
   
    //如果Launcher在加载完成之前被强制暂停,那么需要通过这个回调方法通知Launcher
    //在它再次显示的时候重新执行加载过程
    public boolean setLoadOnResume();
    //获取当前屏幕序号
    public int getCurrentWorkspaceScreen();
    //启动桌面数据绑定
    public void startBinding();
    //批量绑定桌面组件:快捷方式列表,列表的开始位置,列表结束的位置,是否使用动画
    public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end,
                          boolean forceAnimateIcons);
    //批量绑定桌面页,orderedScreenIds 序列化后的桌面页列表
    public void bindScreens(ArrayList<Long> orderedScreenIds);
    public void bindAddScreens(ArrayList<Long> orderedScreenIds);
    //批量绑定文件夹,folders 文件夹映射列表
    public void bindFolders(LongArrayMap<FolderInfo> folders);
    //绑定任务完成
    public void finishBindingItems();
    //批量绑定小部件,info 需要绑定到桌面上的小部件信息
    public void bindAppWidget(LauncherAppWidgetInfo info);
    //绑定应用程序列表界面的应用程序信息,apps 需要绑定到应用程序列表中的应用程序列表
    public void bindAllApplications(ArrayList<AppInfo> apps);
    // Add folders in all app list.
    public void bindAllApplications2Folder(ArrayList<AppInfo> apps, ArrayList<ItemInfo> items);
    //批量添加组件
    public void bindAppsAdded(ArrayList<Long> newScreens,
                              ArrayList<ItemInfo> addNotAnimated,
                              ArrayList<ItemInfo> addAnimated,
                              ArrayList<AppInfo> addedApps);
    //批量更新应用程序相关的快捷方式或者入口
    public void bindAppsUpdated(ArrayList<AppInfo> apps);
    public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated,
            ArrayList<ShortcutInfo> removed, UserHandleCompat user);
    public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
    public void bindRestoreItemsChange(HashSet<ItemInfo> updates);
    // 从桌面移除一些组件,当应用程序被移除或者禁用的时候调用
    public void bindComponentsRemoved(ArrayList<String> packageNames,
                    ArrayList<AppInfo> appInfos, UserHandleCompat user, int reason);
    public void bindAllPackages(WidgetsModel model);
    //全局搜索或者搜索属性更新
    public void bindSearchablesChanged();
    public boolean isAllAppsButtonRank(int rank);
    /**
     * 指示正在绑定的页面
     * @param page  桌面页序号
     */
    public void onPageBoundSynchronously(int page);
    //输出当前Launcher信息到本地文件中
    public void dumpLogsToLocalData();
}

(2)线程处理

@Thunk DeferredHandler mHandler = new DeferredHandler();
@Thunk LoaderTask mLoaderTask;
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
@Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper());

Launcher和LauncherModel运行在Launcher这个应用程序的主线程中, sWorkerThread只是Launcher应用程序主线程下的一个子线程,对于线程和线程之间的消息交互,一个比较好的方案是将任务抛到目标线程的处理器中,为此,LauncherModel为sWorkerThread在主线程中创建了一个处理器,以实现sWorkerThread和Launcher所在进程之间的信息交互。

(3)广播接口:

LauncherModel继承了BroadcastReceiver,因此可以接收来自Launcher或其他地方的广播,在onReceive(Context context, Intent intent)方法中做出相应的处理。


来个分割线,分析上面加载绑定数据过程的几个方法:

LauncherModel负责桌面数据的加载,即调用startLoader方法启动线程,加载数据。


                
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值