Android Handler asynchronous invoke modify interface with main thread

Source: Internet
Author: User

In the process of Android programming, if an operation in the activity will run for a long time, for example: Download the file. This time if the main thread to download files directly, the activity will cause the death of the phenomenon, and if the time is more than 5 seconds, there will be ANR error.

In this case, you can use handler to handle it.

The main classes involved are: Handler, Thread, Message, MessageQueue, Looper, Handlerthread

If this is the case, you can use only handler, message, and thread to resolve it. Processes the download file in thread and, after the end, sends a message to handler. The handler modifies the interface after receiving the message.

If you just don't want to download the file in the interface thread, then you just need to create a new thread to process the downloaded file, why use handler? Because Android interface thread is not secure, so if the interface is changed directly in thread, it will be an error, so use handler to handle it. When getting handler in the interface thread, handler will be in the same thread as the interface thread, so the handler modification interface will not error.

1, handler to rewrite the Handlemessage method, to handle the logic of modifying the interface.

Handler =NewHandler () {@Override Public voidhandlemessage (Message msg) {//TODO auto-generated Method Stub                Super. Handlemessage (msg); Switch(msg.what) { CaseMessagetype.progresstype:intArg1 =Msg.arg1; if(Arg1 >=maxprogress) {Toast.maketext (mainactivity). This, "Progress is OK", Toast.length_short); return; } Else if(Arg1 < 0) {arg1= 0;                    } progressbar.setprogress (ARG1);  Break; default :                                         Break; }            }        };

Description

    • The handler constructor with no parameters is used here, which means to get the looper of the current thread, and the main thread creates a looper by default when it is created, so you can use the handler parameterless constructor directly in the main thread's activity.
    • If you want to get the looper of the main thread in the main thread, you can get it using the Looper.mylooper () method.
    • In other threads to get the looper of the main thread, it needs to be obtained using the Looper.getmainlooper () method, which can also be obtained using this method in the main thread.
    • In other threads, if you use the Looper.mylooper () method directly, you get to null.

2, thread in the download after the file (I used the timertask and timer to achieve 100 milliseconds progress plus 1), send messages to handler.

 Public classMyprogresstimertaskextendsTimerTask {PrivateHandler Handler; Private intcount;  PublicMyprogresstimertask (Handler Handler) { This. Handler =handler; Count= 0; } @Override Public voidrun () {//TODO auto-generated Method Stubcount++; Message Message=Handler.obtainmessage (); Message.what=Messagetype.progresstype; Message.arg1=count;                Handler.sendmessage (message); Looper Looper=Looper.mylooper (); if(NULL==Looper) {System.out.println (">>>>>>>>>>>>>>>>looper.mylooper is null<<<<<< <<<<<<<< "); }     }}

3. When the Start button is clicked, start the timer, and when you click Stop, close the timer. Instead of using a timer, you can use thread to sleep for a while in thread and still achieve the desired effect. At the same time, both ways can operate on the activity, there will be no sense of panic.

ProgressBar =(ProgressBar) Findviewbyid (R.id.progressbar); Maxprogress=Progressbar.getmax (); Btnstartprogress=(Button) Findviewbyid (r.id.btnstartprogress); Btnstartprogress.setonclicklistener (NewView.onclicklistener () {@Override Public voidOnClick (View v) {//TODO auto-generated Method StubTask =NewMyprogresstimertask (handler); Timer=NewTimer (); Timer.schedule (Task,1000, 100);                }        }); Btnstopprogress=(Button) Findviewbyid (r.id.btnstopprogres); Btnstopprogress.setonclicklistener (NewView.onclicklistener () {@Override Public voidOnClick (View v) {//TODO auto-generated Method Stub                if(Task! =NULL) {task.cancel (); }                if(Timer! =NULL) {timer.cancel (); } Task=NULL; Timer=NULL; }        });

Note: It is recommended to use the Handler.obtainmessage () and Message.obtain () methods when generating a message, because both methods (in fact, eventually call Message.obtain () method) is not a simple new object. The parsing code shows that it first determines whether a message is available in the message pool (the message linked list, which is indicated by spool to start the message), and if not, creates a new message.

Main thread:

Activity is drawn in the main thread, and the main thread creates the Looper object when it is created, so when the interface thread uses handler, there is no need to consider creating the looper problem. Is that all the operations of a component, such as activity, in the main thread? The experiment found that the basic can be understood, of course, if you create a new thread in the component, the operation of the new thread is certainly not possible in the main threads (such as the new thread, the 1--100000 in thread). In addition to this operation, it can be understood that both are handled in the main thread, even though the component was created by the new thread called StartActivity.

I wrote such a piece of code. First, start a new thread in the activity that starts, and start an activity, Service, Broadcastreceiver, respectively, in this new thread. The current thread is printed in the activity's OnCreate, OnStart, Onresume, OnPause, OnStop, OnDestroy, Onrestart, Onactivityresult methods, and the result is the main thread. The same effect is in the OnCreate and Broadcastreceiver onreceive of the service. So basically it can be said that the operation of the component is carried out in the main thread.

Therefore, if the main purpose of handler is to modify the interface, then the handlerthread will not need to use. However, if you consider such a scenario, in the newly-started thread A, the task is too many, and the other threads must be started, and thread a needs to get the return results of the other threads. At this point, the use of handlerthread may be very convenient to solve the problem. Looper use should be very few, the role of Handlerthread is to shield off Looper, the direct use of looper more complex, You need to use Looper.prepare first, and then call Looper.loop at the end of all operations to iterate through the messages in the message queue. After using Handlerthread, the program will be extremely simplified.

  

Resources:

Deep understanding of Android Message processing system--looper, Handler, Thread

In-depth analysis of Android messaging mechanisms

The use of Android Handlerthread and its demo

Android Handler asynchronous invoke modify interface with main thread

Related Article

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.