The android. View. viewroot $ calledfromwrongthreadexception exception will occur when the sub-thread updates the UI.

Source: Internet
Author: User

The sub-thread updates the UI.


Obviously, if your program needs to execute time-consuming operations, it would be wrong if the main thread is responsible for executing the operation as in the previous example. Therefore, we need to create a new sub-thread in the onclick method to call Google API to obtain weather data. The easiest way to think of Android Developers is as follows:


Public void onclick (view v) {// create a sub-thread to obtain the weather information from the network for time-consuming operations. New thread () {@ override public void run () {// obtain the city name string city = edittext. gettext (). tostring (); // call the Google weather API to query the weather conditions of the specified city on the day string weather = getwetherbycity (city ); // display the weather information on the title settitle (weather );}}. start ();}

However, unfortunately, you will find that android will prompt that the program is terminated due to an exception. Why do simple code on other platforms still encounter errors when running on Android? If you observe the log information printed in logcat, you will find such an error log:

Android. View. viewroot $ calledfromwrongthreadexception: only the original thread that created a view hierarchy can touch its views.

From the error message, it is not difficult to see that android prohibits other sub-threads from updating the attempt created by the UI thread. In this example, the title that displays the weather information is actually a textview created by the UI thread. Therefore, an error occurs when you change the textview in a subthread. This shows that it violates the single-thread model principle: Android UI operations are not thread-safe and must be executed in the UI thread.

2.2 Message Queue

In the single-thread model, Android designs a message queue to solve similar problems. The message queue can be used between threads to exchange information with handler and logoff components. They are described as follows:

L Message Queue

Message Queue is a message queue used to store messages published through handler. A message queue is usually attached to a thread that creates it. You can use logoff. myqueue () to obtain the message queue of the current thread. Android will create an associated message queue for the UI thread by default at the first startup, which is used to manage some upper-layer components of the program, such as activities and broadcast receivers. You can create handler and UI thread communication in your child thread.

L Handler

With handler, you can publish or process a message or a runnable instance. No handler will be managed with the only thread and the message queue of the thread. When you create a new handler, by default, it will be associated with the thread that created it and the message queue of the thread. That is to say, if you publish a message through handler, the message will only be sent to the Message Queue associated with it, and of course only the messages in the Message Queue can be processed.

The main methods are as follows:

1) public final Boolean sendmessage (Message MSG)

Put the message into the Message Queue associated with the handler and put it after all the messages not processed before the current time.

2) Public void handlemessage (Message MSG)

The Thread associated with the message queue receives and processes messages by calling the handlemessage method of handler. handlemessage is usually implemented by subclass handler.

L Logoff

Logoff acts as a bridge between handler and message queue. The program component first transmits the message to logoff through handler, and logoff puts the message into the queue. Logoff also broadcasts messages in the message queue to all handler. handler receives the message and calls handlemessage for processing.

1) You can use the logoff static method logoff. mylogoff to obtain the logoff instance of the current thread. If the current thread is not linked to a logoff instance, this method will return null.

2) You can use the static Looper. getmainlo method to obtain the looper instance of the main thread.

The relationships between threads, message queues, handler, and logoff can be shown in a diagram:

After understanding the design idea of message queue and its related components, we will re-implement the weather forecast case through message queue:


Private edittext; private handler messagehandler; @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); edittext = (edittext) findviewbyid (R. id. weather_city_edit); button = (button) findviewbyid (R. id. goquery); button. setonclicklistener (this); // obtain the logoff instance of the current thread. Because the current thread is a UI thread, you can also use logoff. getmainlogoff () to get logoff = logoff. mylogoff (); // you do not need to set logoff here, because handler uses the loginmessagehandler of the current thread by default );} @ override public void onclick (view v) {// create a subthread to perform time-consuming network connection work. New thread () {@ override public void run () {// name of the city entered by the activity user string city = edittext. gettext (). tostring (); // call the Google weather API to query the weather condition of the specified city on the day string weather = getwetherbycity (city); // create a message object, and assign the obtained weather information to the message object message = message. obtain (); message. OBJ = weather; // messagehandler with weather conditions is published through handler. sendmessage (Message );}}. start () ;}// subclass A handler class messagehandler extends handler {public messagehandler (Looper loler) {super (loage) ;}@ override public void handlemessage (Message MSG) {// process received messages and display the weather information on the title settitle (string) MSG. OBJ );}}

The weather forecast program modified through the Message Queue can be successfully run, because the handlemessage method of handler is actually called by the UI Thread associated with the message queue, updating the title in the UI thread does not violate the android single-thread model principle.



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.