Android Asynchronous Update ui-thread pool-future-handler instance analysis

Source: Internet
Author: User
Tags message queue

In the process of developing Android, we put time-consuming tasks into sub-threading and refreshing during the process of processing time-consuming tasks and UI interactions. Here are two questions I believe most developers will encounter:

1. The data often needs to be read and updated, and it is time consuming to refresh the UI in steps.

2. After switching the UI interface, how to stop the data that is being read in the child thread without flushing the old data to the new UI interface.

Currently most of the online tutorials are simply handler.postdelayed (), Thread + Handler, async, etc., only for simple one-time refresh. Someone might say that I can create a child thread refresh in a way that is constantly new thread, and then pass a message back to update the UI, but this constant new will have the problem of high performance consumption and data synchronization.

As for the above two issues, I would like to introduce the use of +future+handler with the thread pool.

To better understand how the asynchronous update UI works, here's the following thread + Handler + Looper + message model, as shown in 1:

Figure 1 Thread + Handler + Looper + message model

Figure 1 clearly shows us how Message Queuing is handled in Looper, here are two important points: (1) sub-threads can also manage messages through looper, but need to add looper.prepare () and Looper.loop () To realize the message loop; (2) The UI main thread does not need to implement prepare () and loop () because it is already implemented by default in the main thread.

Now let's introduce some basic concepts of thread pool +future+handler and use demo instance.

Thread pool

is an object pool of thought, open up a piece of memory space, which contains many (not dead) threads, pool thread execution schedule by the pool manager to handle. When a thread task is taken from a pool, the threads object is pooled after execution, which avoids the performance overhead of repeatedly creating thread objects and saves system resources. If you repeatedly create and destroy threads in your program, you will have a serious effect on the speed of the program, sometimes even crash out the program. Here we use the simple Executorservice class.

Future

The future mode can be described as follows: I have a task to give to the Future,future to complete this task for me. I can do anything I want to do during the period. After a while, I handy can take the results from the future. It is equivalent to an order form, after a period of time can take the order to pick up, this period can do anything else. One of the future interface is the order form, the real processing order is the executor class, which according to the requirements of the future interface to produce products.

Handler

The bridge connecting the child thread and the main thread can communicate with the main thread by SendMessage or post.

Said so much, if there are not too familiar with the basic concept of children's shoes can first move to the last reference to see the article and then come back to see this article, here directly on the code dry.

Method one: Using SendMessage to realize

 Public classMyActivity extends Activity {PrivateFinal String TAG =Demoexecutorservice; @Override Public voidonCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (R.layout.main);        Initfindview ();    Setlistener (); }     PrivateTextView Mtitle; PrivateButton MBtn; Private voidInitfindview () {Mtitle=(TextView) Findviewbyid (r.id.title); MBtn=(Button) Findviewbyid (R.ID.BTN); }     Private voidSetlistener () {Mbtn.setonclicklistener (NewView.onclicklistener () {@Override Public voidOnClick (view view) {Testcallback Testcallback=NewTestcallback ();            Testcallback.loadtohandler ();    }        }); }     Private classTestcallback { PublicTestcallback () {log.d (TAG, # # # #TestCallBack===Constructor); }          Public voidLoadtohandler () {Handler MyHandler=NewHandler (Getmainlooper ()) {@Override Public voidhandlemessage (Message msg) {LOG.D (TAG, ###### #receive the msg?? what = +msg.what); intnum =Msg.what; Switch(num) { Case 1: Mtitle.settext (##### #Yeah, we receive the first MSG1);  Break;  Case 2: Mtitle.settext (##### #Yeah, we receive the second MSG2);  Break; default:                             Break;            }                }            };        Testexecutorhandler (MyHandler); }    }     PrivateFinal Executorservice Mexecutor =Executors.newsinglethreadexecutor (); Future<!--?-->Mtask;     Boolean msendmsg;  Public voidTestexecutorhandler (Final Handler Handler) {log.d (TAG, ####### #testExecutorHandler, Mtask=  +mtask); if(Mtask! =NULL) {            //by canceling Mtask, to achieve the purpose of a previously queued but not running submit task, the flag bit does not let it send msg to the UI main thread update.Mtask.cancel (false); LOG.D (TAG, ####### #mTask. Iscannel? ===  +mtask.iscancelled ()); Msendmsg=false; } Runnable R=NewRunnable () {@Override Public voidrun () {msendmsg=true; Try{log.d (TAG, # # #step1# # # #start to sleep 6s.); Thread.Sleep (6000); } Catch(interruptedexception e) {e.printstacktrace ();                } Message msg; LOG.D (TAG, #######1111Msendmsg = = = +msendmsg); if(msendmsg) {msg=Handler.obtainmessage (); Msg.what=1;                Handler.sendmessage (msg); } Else {                    return ; } log.d (TAG, # # # #step2# # # #start to sleep 4s.); Try{Thread.Sleep (4000); } Catch(interruptedexception e) {e.printstacktrace (); }                //If you do not re-obtainmessage, you will receive the following error, because it has been recycled, so it is wrong. You need to Obtainmessage () again.//E/androidruntime (1606): Java.lang.IllegalStateException:The specified Message queue synchronization Barrier tokens have not been posted or have already been removed.LOG.D (TAG, #######22222Msendmsg = = = +msendmsg); if(msendmsg) {msg=Handler.obtainmessage (); Msg.what=2;                Handler.sendmessage (msg); } Else {                    return ; }            }        };//Mexecutor.submit (R); //If this is the case, it will not enter the future mission, so that each submission will be executed sequentially. Mtask =Mexecutor.submit (R); } }

The results and printing are as shown in 2 and 3:

Figure 4 Using multiple clicks to simulate a constant call to refresh the UI, the background execution will simply keep the current task and the last commit task, and the intermediate task is futurecancel out. and the current old task is also under the control of the flag bit, does not sendmessage the update content, thus does not affect the last UI refresh.

Method Two: Using runnable to implement the update:

Since some of the methods are the same as above, it is important to see that the complete code can be downloaded below, just the core code.

 Public voidloadtorunnable () {Runnable runable=NewRunnable () {@Override Public voidrun () {LOG.D (TAG, ######## #Ok:1111Let update callback1 ...); Mtitle.settext (# # # #Yeah, Refreshinchrunnable, Callback1);            }           }; Runnable Runable2=NewRunnable () {@Override Public voidrun () {LOG.D (TAG, ##### #Ok, let update Callback2, ...); Mtitle.settext (# # # #Callback2 Update Success!!!);            }           };       Testexecutorrunnable (runable, Runable2, Getmainlooper ()); }   }
 Public voidtestexecutorrunnable (Final Runnable callback, final Runnable Callback2, final Looper loop ER) {log.d (TAG, # # # #testExecutor # #mTask: #### =  +mtask); if(Mtask! =NULL) {www.2cto.com Mtask.cancel (false);//true indicates a forced cancellation, an exception occurs, and false means that the wait for the task ends after it is canceled. Msendmsg =false; } Runnable R=NewRunnable () {@Override Public voidrun () {msendmsg=true; Try{log.d (TAG, # # #Step1# # # #Async run after submit...## #sleep 6s); Thread.Sleep (6000); } Catch(interruptedexception e) {e.printstacktrace (); }                if(Callback! =NULL&&msendmsg) {//Handler Handler = new Handler (); //Not with it, should use the Looper.Handler Handler =NewHandler (Looper);                Handler.post (callback); }                 Try{log.d (TAG, # # #Step2# # # #Async run after submit...## #sleep 4s); Thread.Sleep (4000); } Catch(interruptedexception e) {e.printstacktrace (); }                if(Callback2! =NULL&&msendmsg) {Handler Handler=NewHandler (Looper);                Handler.post (CALLBACK2);         }            }        }; Mtask=Mexecutor.submit (R); }

Android Asynchronous Update ui-thread pool-future-handler instance analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.