Launcher2折腾之路(4)
LauncherMode.java的回调机制与异步操作。
1,回调机制
“if you call me, i will call back”,说白了,就是有相互依赖关系的两个类之间的互相调用;
用java的回调机制来实现C语言中的函数指针的传递;
接口中有许多作用,除了统一方法接口、引用传递(数据交互)之后,还有回调机制,在Android中,这篇文章总结得可以
http://blog.csdn.net/superkris/article/details/7697002
讲讲Launcher中LauncherModel和Launhcer的回调机制
LaucherModel.java
1 | public interface Callbacks { |
2 | |
3 | public boolean setLoadOnResume(); |
4 | |
5 | public int getCurrentWorkspaceScreen(); |
6 | |
7 | public void startBinding(); |
8 | |
9 | public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end); |
10 | |
11 | public void bindFolders(HashMap<Long,FolderInfo> folders); |
12 | |
13 | public void finishBindingItems(); |
14 | |
15 | public void bindAppWidget(LauncherAppWidgetInfo info); |
16 | |
17 | public void bindAllApplications(ArrayList<ApplicationInfo> apps); |
18 | |
19 | public void bindAppsAdded(ArrayList<ApplicationInfo> apps); |
20 | |
21 | public void bindAppsUpdated(ArrayList<ApplicationInfo> apps); |
22 | |
23 | public void bindComponentsRemoved(ArrayList<String> packageNames, |
24 | |
25 | ArrayList<ApplicationInfo> appInfos, |
26 | |
27 | boolean matchPackageNamesOnly); |
28 | |
29 | public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts); |
30 | |
31 | public boolean isAllAppsVisible(); |
32 | |
33 | public boolean isAllAppsButtonRank( int rank); |
34 | |
35 | public void bindSearchablesChanged(); |
36 | |
37 | public void onPageBoundSynchronously( int page); |
38 | |
39 | } |
40 | |
41 |
Laucher.java
1 | public int getCurrentWorkspaceScreen () { |
2 | |
3 | if (mWorkspace != null) { |
4 | |
5 | return mWorkspace.getCurrentPage(); |
6 | |
7 | } else { |
8 | |
9 | return SCREEN_COUNT / 2; |
10 | |
11 | } |
12 | |
13 | } |
14 | |
15 |
我觉得LauncherMode.java和Launcher.java的利用callback的回调接口机制来交互主要是体现两个类的不同分工。LauncherMode主要是维护Laucher的后台数据,而Launcher这个类主要是Launcher的前台运行状态,前台与后台需要交互,就使用回调接口最好不过了。
2,异步操作
数据加载免不了要进行数据库操作等等,作为一个Launhcer用户端的体验至关重要,高效合理的处理这步非常重要。
2.1,先看看加载的顺序
public void startLoader(boolean isLaunching, int synchronousBindPage)
=》
mLoaderTask = new LoaderTask(mApp, isLaunching);
=》
private class LoaderTask implements Runnable
在Luncher中各个应用的图片和数据加载都是在LauncherModer这个类加载完成了。在这个LoadTask中主要包括以下2步
a,loadAndBindWorkspace();
b,loadAndBindAllApps();
2.1,异常操作的几种类型
a,通过一个runOnMainThreaad启动一个runnable
r = new Runnable() {
public void run() {
Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.onPageBoundSynchronously(currentScreen);
}
}
};
runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
b,通过Handle.post()方法来执行一个Runnable
mHandler.post(new Runnable() {
public void run() {
final long t = SystemClock.uptimeMillis();
if (callbacks != null) {
if (first) {
callbacks.bindAllApplications(added);
} else {
callbacks.bindAppsAdded(added);
}
if (DEBUG_LOADERS) {
Log.d(TAG, "bound " + added.size() + " apps in "
+ (SystemClock.uptimeMillis() - t) + "ms");
}
} else {
Log.i(TAG, "not binding apps: no Launcher activity");
}
}
});
c,通过enqueuePackageUpdated来更新安装卸载APK的数据
void enqueuePackageUpdated(PackageUpdatedTask task) {
sWorker.post(task);
}
private class PackageUpdatedTask implements Runnable {
}
其实跟进去,殊途同归,都是handler.post方法,这里,不得不要看张图片(来自网络)