这是Launcher的一个例子,在Package改变的时候,通知更新消息。
- 主线程收到事件
- 开启额外线程处理事情
- 处理完回到主线程,更新UI
- 查询的时候,只做查询相关的,修改的时候,只做修改相关的
1.当事件发生的时候,onReceive收到
if (Intent.ACTION_PACKAGE_CHANGED.equals(action)
|| Intent.ACTION_PACKAGE_REMOVED.equals(action)
|| Intent.ACTION_PACKAGE_ADDED.equals(action)) {
final String packageName = intent.getData().getSchemeSpecificPart();
final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING,false);
int op = PackageUpdatedTask.OP_NONE;//设置初始状态为一个状态
if (packageName == null || packageName.length() == 0) {
// they sent us a bad intent
return;
}
if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
op = PackageUpdatedTask.OP_UPDATE;
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
if (!replacing) {
op = PackageUpdatedTask.OP_REMOVE;
}
} else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
if (!replacing) {
op = PackageUpdatedTask.OP_ADD;
} else {
op = PackageUpdatedTask.OP_UPDATE;
}
}
if (op != PackageUpdatedTask.OP_NONE) {//这个判断很巧妙
enqueuePackageUpdated(new PackageUpdatedTask(op,new String[] { packageName }));//对于这个方法,本可以放在上面每次都执行,但是他们的区别只是在第一个参数,把上面的参数提取出来,单独设定,只有一次调用
}
}
}
2.接下来的处理,放在了其他的线程里
void enqueuePackageUpdated(PackageUpdatedTask task) {
sWorker.post(task);
}sWorker是一个其他线程的Handler,如下:
private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
sWorkerThread.start();
}
private static final Handler sWorker = new Handler(sWorkerThread.getLooper());
3.其他的线程里如下:
import java.util.ArrayList;
private class PackageUpdatedTask implements Runnable {
int mOp;
String[] mPackages;
//前面的状态,之前传进入的第一个参数
public static final int OP_NONE = 0;
public static final int OP_ADD = 1;
public static final int OP_UPDATE = 2;
public static final int OP_REMOVE = 3; // uninstlled
public static final int OP_UNAVAILABLE = 4; // external media unmounted
public PackageUpdatedTask(int op,String[] packages) {
mOp = op;
mPackages = packages;
}
public void run() {
final Context context = mApp;
final String[] packages = mPackages;
final int N = packages.length;
switch (mOp) {
case OP_ADD:
for (int i = 0; i < N; i++) {
//添加的过程只做添加相关的处理,查询跟更改分开
mAllAppsList.addPackage(context,packages[i]);
}
break;
}
//为什么没有直接调用,不清楚其中原因,感觉没有必要
ArrayList<ApplicationInfo> added = null;
if (mAllAppsList.added.size() > 0) {
added = mAllAppsList.added;
mAllAppsList.added = new ArrayList<ApplicationInfo>();
}
if (mAllAppsList.removed.size() > 0) {
...//处理类似
}
//这个处理,added跟removed互补冲突,有added就做added,后面的removed,如果有有removed处理可以进行处理
if (added != null) {
final ArrayList<ApplicationInfo> addedFinal = added;
//做完事情以后,回到调用主线程的handler,mHandler.post(new Runnable() {
public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
if (callbacks == cb && cb != null) {
callbacks.bindAppsAdded(addedFinal);//主线程更新UI
}
}
});
}
if (removed != null) {
...//处理类似
}
}
}