为什么放到另外一个线程?因为加载的过程有时候会很漫长,在UI线程可能会造成ANR(如果你对Handler和HandlerThread还不太懂,请一定搞清楚Handler消息传递的机制,你一定会在将来的工作中用到他的)。这里的sWorker是一个Handler,可以传递一个Runnable对象,并在相关联的线程中执行。sWorker对应的线程是sWorkerThread,sWorkerThread在LauncherModel类加载的时候就已经开始运行了。
sWorkThread会执行LoaderTask的run方法,run方法里面最重要的就属于loadAndBindWorkspace方法了。在上面的图中,我已经画出了他的功能,先是在数据库读取数据,看看有什么需要增加,有什么需要删除;再在界面上显示。显示完了之后桌面其实也就启动完了。
loadWorkspace:
loadWorkspace有将近400行,挺多的,其实做的事情就是遍历数据库里的每条记录,判断他的类型,生成对应的ItemInfo对象(ShortcutInfo,FolderInfo,LauncherAppWidgetInfo)
bindWorkspace:
在bindWorkspace里面,用了一个很重要的Callback接口,Launcher.java实现了这些接口,用于更新UI。bindWorkspace新建了几个对象都是current*,other*形式的,这个current*代表的是当前屏的ItemInfo,other*代表的其他屏的ItemInfo,为了加载时候不让用户感觉很慢,就先把当前屏的显示出来,再显示其他的,这个显示的工作都交给了bindWorkspaceItems方法。bindWorkspaceItems会分别加载图标,小工具,和文件夹。
我们具体看下图标的情况:
加载图标用过Callback.bindItems方法来实现他必须在UI层执行,所以在bindWorkspaceItems中已经把这个调用给post到主线程去了。Callback.bindItems方法的职责就是生成图标对应的View,并把它加到CellLayout中。产生View的动作是在Launcher.createShortcut中完成的,他用一个xml布局文件生成BubbleTextView对象,并调用BubbleTextView的applyFromShortcutInfo方法设置图片和标题。View生成好了之后,用Workspace.addInScreenFromBind即可显示在UI上了,这往下就是繁琐的细节了。
文件夹和小工具的加载思路其实都是差不多的,分别调用了Callback.bindFolders和Callback.bindAppWidgets。当这些UI元素都显示完成的时候,桌面也基本上启动完了,开始等待用户 *** 作。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)