"Android Development experience" Come on, classmate, let's discuss the little thing about "update view only on the main thread of the UI"

Source: Internet
Author: User

Reprint Please specify source: http://blog.csdn.net/zhaokaiqiang1992

"View can only be updated in the main thread of the UI."

Is this a familiar sentence?

Come on, man, take a look at the following example

@Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( R.layout.activity_main); TV = (TextView) Findviewbyid (r.id.tv); Thread.CurrentThread (). SetName ("Uithread"); new Looperthread ("Non-Main thread modification"). Start (); Private class Looperthread extends Thread {private string Text;public looperthread (String text) {this.text = text;} @Overridepublic void Run () {Thread.CurrentThread (). SetName ("Otherthread"); Tv.settext (text);}}

The code says so, isn't it a tease! It must have collapsed! But if you try, you will find that most of them will not collapse. As for the few causes of collapse, I'll say it later.

You might be wondering, isn't "view only being updated in the main thread of the UI"? You're updating the view in a sub-thread, why don't you shoot it?

So, if you look at the code below, it's definitely going to explode.

public void Changenoui (view view) {New Looperthread ("Non-Main thread modification"). Start ();

The calling code is the same as above, except that we set a click event for a button and then call it by hand, so it will definitely crash and report what's wrong?

Report the following error

02-02 16:44:38.786:e/androidruntime (17907): FATAL exception:otherthread02-02 16:44:38.786:e/androidruntime (17907): Process:com.example.demo, pid:1790702-02 16:44:38.786:e/androidruntime (17907): android.view.viewrootimpl$ Calledfromwrongthreadexception:only the original thread that created a view hierarchy can touch its views.02-02 16:44:38. 786:e/androidruntime (17907): at Android.view.ViewRootImpl.checkThread (viewrootimpl.java:6226) 02-02 16:44:38.786:e /androidruntime (17907): at Android.view.ViewRootImpl.invalidateChildInParent (viewrootimpl.java:883) 02-02 16:44:38.786:e/androidruntime (17907): at Android.view.ViewGroup.invalidateChild (viewgroup.java:4320) 02-02 16:44:38.786:e/androidruntime (17907): at Android.view.View.invalidate (view.java:10947) 02-02 16:44:38.786:e/ Androidruntime (17907): at Android.view.View.invalidate (view.java:10902) 02-02 16:44:38.786:e/androidruntime (17907) : At Android.widget.TextView.checkForRelayout (textview.java:6673) 02-02 16:44:38.786:e/androidruntime (17907): At Android.widget.TextView.setText (textview.java:3860) 02-02 16:44:38.786:e/androidruntime (17907): at Android.widget.TextView.setText (textview.java:3718) 02-02 16:44:38.786:e/androidruntime (17907): at Android.widget.TextView.setText (textview.java:3693) 02-02 16:44:38.786:e/androidruntime (17907): at Com.example.demo.mainactivity$looperthread.run (mainactivity.java:78)

This means that only the thread that created the view hierarchy can modify the view, and we update the view in the non-UI main thread, so we get an error.

But you haven't said why the first method of calling is not an error!!!

Do not worry, first look at the above error message, there are many things to study it!

We start from below to see, first of all Looperthread.run () error, why the error, and then go up, because we call SetText, Then up is textview.checkforrelayout, and then the above is invalidate, we modified the text, it must be invalidate ah, who called it? The original is viewgroup.invalidatechild, looking for AH find, finally found the culprit, Viewrootimpl.checkthread () Error!

What the hell is Viewrootimpl? This thing is very powerful, you just need to know that it can do a lot of interface-related things are OK, in fact, I also only know a little bit about this class ...

Checkthread () What exactly did Ah, the error! Viewrootimpl is a hidden class, we can only go to see the source code, the source is as follows

void Checkthread () {        if (mthread! = Thread.CurrentThread ()) {            throw new Calledfromwrongthreadexception (                    " Only the original thread, created a view hierarchy can touch its views. ");        }    }

This is the method of error! Viewrootimpl is attached to the class of Attachinfo, and Attachinfo is the view of a hidden class, you can not see in eclipse, you need to directly see the framework of the source code. So, the Thread.CurrentThread () here is the main thread of the UI, which is where we decide whether we have modified the view in the non-UI mainline.

Then the question comes again, why the first way, will not error it!!!

OK, don't freak out, let's go back to the life cycle of the activity. By! And how does the life cycle of activity relate?

Activity in OnCreate in the interface of the data preparation, OnStart (), the activity of the interface is visible to the user, then know what is the use of these? Of course it works! The difference between the above two methods of invocation is different at the time of the call! One is to turn on thread invocation in OnCreate, one is we call manually, suggesting that the second method is called after Onresume!

This difference in call timing determines the meaning of settext in the code!

The first approach, although settext in the sub-thread, but this time the view has not been drawn, so it does not call after the invalidate, but the equivalent of just set TextView a property, not invalidate, there is no subsequent method calls, In the final analysis, will not call Viewrootimpl Checkthread, also will not error. And the second method, after calling SetText, will be thrown after a series of method calls, the view to refresh the interface, ViewGroup to update the layout, calculate the size of the sub-view position, to the end, Viewrootimpl will Checkthread, the collapse.

So, strictly speaking, although the first method sets the View property on a sub-thread, it does not boil down to the "Update View" category, because it has not been drawn yet, there is no so-called update.

So, why does the overwhelming majority not say an error? This is because if we start the sub-thread in OnCreate, and the child thread takes a time-consuming operation, such as Thread.Sleep, then the child thread will crash when the SetText is called, because then OnStart and Onresume are executed, You want to update the view in the sub-thread again, then the door is not!


Do not know if there are classmates will think: I remember in the sub-thread with a toast will also error, plus looper.prepare and looper.loop on it, can you do this?

The answer is of course not.

Toast and view are not the same in nature, the toast in the child thread error, because the toast display needs to be added to a MessageQueue, and then looper out, sent to handler call display, sub-threading because there is no looper, So we need to add looper.prepare and Looper.loop to create a looper, but in essence, this is still called on the child thread, so it will be an error!

So why does Android require the view to be changed only in the main thread of the UI? This is about Android's single-threaded model, because the resulting thread synchronization and thread-safety issues will be cumbersome if the view is supported for multithreading, so Android is dead and the view must be in the UI thread, simplifying system design.

OK, hope that the above mentioned can help you, if there is doubt or I have said wrong place, welcome to correct.


"Android Development experience" Come on, classmate, let's discuss the little thing about "update view only on the main thread of the UI"

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.