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: Java code

  1. Public void onclick (view v ){
  2. // Create a subthread to perform time-consuming operations to obtain weather information from the network
  3. New thread (){
  4. @ Override
  5. Public void run (){
  6. // Obtain the city name entered by the user
  7. String city = edittext. gettext (). tostring ();
  8. // Call the Google weather API to query the weather conditions of the specified city on the current day
  9. String weather = getwetherbycity (city );
  10. // Display the weather information on the title
  11. Settitle (weather );
  12. }
  13. }. Start ();
  14. }
View plaincopy to clipboardprint?
  1. Public void onclick (view v ){
  2. // Create a subthread to perform time-consuming operations to obtain weather information from the network
  3. New thread (){
  4. @ Override
  5. Public void run (){
  6. // Obtain the city name entered by the user
  7. String city = edittext. gettext (). tostring ();
  8. // Call the Google weather API to query the weather conditions of the specified city on the current day
  9. String weather = getwetherbycity (city );
  10. // Display the weather information on the title
  11. Settitle (weather );
  12. }
  13. }. Start ();
  14. }

Public void onclick (view V) {</P> <p> // create a subthread to obtain weather information from the network during time-consuming Operations </P> <p> New thread () {</P> <p> @ override </P> <p> Public void run () {</P> <p> // obtain the city name entered by the user </P> <p> string city = edittext. gettext (). tostring (); </P> <p> // call the Google weather API to query the weather conditions of the specified city on the day </P> <p> string weather = getwetherbycity (city ); </P> <p> // display the weather information on the title </P> <p> settitle (weather ); </P> <p >}</P> <p> }. start (); </P> <p >}< br/>

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:

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

Java code
  1. Private edittext;
  2. Private handler messagehandler;
  3. @ Override
  4. Public void oncreate (bundle savedinstancestate ){
  5. Super. oncreate (savedinstancestate );
  6. Setcontentview (R. layout. Main );
  7. Edittext = (edittext) findviewbyid (R. Id. weather_city_edit );
  8. Button button = (button) findviewbyid (R. Id. goquery );
  9. Button. setonclicklistener (this );
  10. // Obtain the logoff instance of the current thread. Because the current thread is a UI thread, you can also get it through logoff. getmainlogoff ().
  11. Logoff logoff = logoff. mylogoff ();
  12. // You do not even need to set logoff here, because handler uses the Logoff of the current thread by default.
  13. Messagehandler = new messagehandler (logoff );
  14. }
  15. @ Override
  16. Public void onclick (view v ){
  17. // Create a subthread for time-consuming network connection
  18. New thread (){
  19. @ Override
  20. Public void run (){
  21. // Name of the city entered by the activity user
  22. String city = edittext. gettext (). tostring ();
  23. // Call the Google weather API to query the weather conditions of the specified city on the current day
  24. String weather = getwetherbycity (city );
  25. // Create a message object and assign the obtained weather information to the message object
  26. Message message = message. Obtain ();
  27. Message. OBJ = weather;
  28. // Send messages with weather conditions through Handler
  29. Messagehandler. sendmessage (Message );
  30. }
  31. }. Start ();
  32. }
  33. // Subclass A handler
  34. Class messagehandler extends handler {
  35. Public messagehandler (low.logoff ){
  36. Super (logoff );
  37. }
  38. @ Override
  39. Public void handlemessage (Message MSG ){
  40. // Process received messages and display the weather information on the title
  41. Settitle (string) msg. OBJ );
  42. }
  43. }
View plaincopy to clipboardprint?
  1. Private edittext;
  2. Private handler messagehandler;
  3. @ Override
  4. Public void oncreate (bundle savedinstancestate ){
  5. Super. oncreate (savedinstancestate );
  6. Setcontentview (R. layout. Main );
  7. Edittext = (edittext) findviewbyid (R. Id. weather_city_edit );
  8. Button button = (button) findviewbyid (R. Id. goquery );
  9. Button. setonclicklistener (this );
  10. // Obtain the logoff instance of the current thread. Because the current thread is a UI thread, you can also get it through logoff. getmainlogoff ().
  11. Logoff logoff = logoff. mylogoff ();
  12. // You do not even need to set logoff here, because handler uses the Logoff of the current thread by default.
  13. Messagehandler = new messagehandler (logoff );
  14. }
  15. @ Override
  16. Public void onclick (view v ){
  17. // Create a subthread for time-consuming network connection
  18. New thread (){
  19. @ Override
  20. Public void run (){
  21. // Name of the city entered by the activity user
  22. String city = edittext. gettext (). tostring ();
  23. // Call the Google weather API to query the weather conditions of the specified city on the current day
  24. String weather = getwetherbycity (city );
  25. // Create a message object and assign the obtained weather information to the message object
  26. Message message = message. Obtain ();
  27. Message. OBJ = weather;
  28. // Send messages with weather conditions through Handler
  29. Messagehandler. sendmessage (Message );
  30. }
  31. }. Start ();
  32. }
  33. // Subclass A handler
  34. Class messagehandler extends handler {
  35. Public messagehandler (low.logoff ){
  36. Super (logoff );
  37. }
  38. @ Override
  39. Public void handlemessage (Message MSG ){
  40. // Process received messages and display the weather information on the title
  41. Settitle (string) msg. OBJ );
  42. }
  43. }

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

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.