This is an example of launcher. When the package changes, an update message is notified.
- The main thread receives the event
- Enable additional threads to handle tasks
- Return to the main thread after processing and update the UI
- During query, only query-related items are supported. During modification, only related items are modified.
1. When an event occurs, onreceive receives
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; // set the initial state to a State 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) {// this judgment is clever. enqueuepackageupdated (New packageupdatedtask (OP, new string [] {packagename}); // for this method, it can be executed every time on it, but their difference is only in the first parameter. Extract the above parameters and set them separately. Only one call is allowed }}}
2. The subsequent processing is placed in other threads.
void enqueuePackageUpdated(PackageUpdatedTask task) { sWorker.post(task);}
Sworker is the handler of other threads, as follows:
private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");static { sWorkerThread.start();}private static final Handler sWorker = new Handler(sWorkerThread.getLooper());
3. Other threads are as follows:
Import Java. util. arraylist; private class packageupdatedtask implements runnable {int MOP; string [] mpackages; // the previous status. The first parameter in the previous step is 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; // uninstlledpublic static final int op_unavailable = 4; // external media unmountedpublic packageupdatedtask (INT op, string [] Packages) {Mop = op; mpackages = packages;} public void run () {final context = Mapp; final string [] packages = mpackages; Final int n = packages. length; Switch (MOP) {Case op_add: For (INT I = 0; I <n; I ++) {// the process of adding only adds the relevant processing, the query and change are separated by mallelizlist. addpackage (context, packages [I]);} break;} // Why is it not called directly? I don't know the reason. I don't think it is necessary to use arraylist <applicationinfo> added = NULL; if (mall1_list. added. size ()> 0) {added = Mallcategory list. added; mall1_list. added = new arraylist <applicationinfo> ();} If (mallappslist. removed. size ()> 0 ){... // processing is similar} // This processing, added and removed conflict with each other, added is implemented when there is added, and removed is followed. If there is removed processing, it can be processed if (Added! = NULL) {final arraylist <applicationinfo> addedfinal = added; // return to the handler and mhandler that call the main thread after the task is finished. post (New runnable () {public void run () {callbacks cb = mcallbacks! = NULL? Mcallbacks. Get (): NULL; If (callbacks = CB & CB! = NULL) {Callbacks. bindincluadded (addedfinal); // The main thread updates the UI }});} If (removed! = NULL) {... // processing is similar }}}