微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Code Fragment- 批量的数据处理放到额外的线程里

这是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) {
        // t@R_502_6478@ 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) {
                    ...//处理类似
                }
	}
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐