"Android Interview" (b): You can't not know the difference between view---plus ID and no ID?

Source: Internet
Author: User

Please respect the original labor results, reproduced please indicate the source: http://blog.csdn.net/cyp331203/article/details/45313125 , do not allow for commercial or profit-making purposes.


The last interview, Android Development, was asked: Do you know what is the difference between adding ID and no ID in the layout file in Android? This I really do not know, blindfolded, can only bite the bullet said: Add the ID will be in the R file to generate the corresponding ID value, and then pulled a point view tree, in short irrelevantly replying ... Although the final interview is over, but this question has been lingering in the heart, lingering. Just review the activity life cycle today and see the relevant knowledge points.


Some of the basics of the onsaveinstantcestate (Bundle outstate) approach to activity have been mentioned in the previous article, so you can go and see:" Android Interview "(a): The activity in the Android save state and data in the end in which method , must admit that the tone of the previous article is too heavy, if there is an offence, in advance to say sorry, I still respect the interviewer, After all, it must be better than me to interview me.


the onsaveinstantcestate in activity


This is pensive from the activity of the onsaveinstantcestate (bundle Outstate) method, the following fast Onsaveinstantcestate (bundle outstate) a few points:


1,onsaveinstantcestate (Bundle outstate) will be called before the activity can be destroyed, that is, the so-called (killble) state, which is mentioned in the previous article


2.onsaveinstantcestate (Bundle outstate) is called before the OnStop () method, but is not guaranteed to be called before or after the OnPause () method.


3, Focus!!! onsaveinstantcestate (Bundle outstate) is not bound to be called, when will it be called? A simple sentence: The system calls Onsaveinstantcestate (Bundle outstate) before the activity enters a state in which the system may kill the activity in a non-applied behavior. method.


4, non-application behavior exit

What is a non-application behavior exit? Application behavior exit activity: such as active call to the finish () method, or actively press the back key, let the activity end. Non-application behavior exits: For example, an activity is in the background, after a long time has not been recalled, or the system current resources are very tense, actively kill off the current activity, release resources for other applications to use.


The logic of this design is very clear: when the system is not sure when the event will not be "allowed" to end the activity, before entering this state, it is necessary to save the data we want, such as the activity has a control state value, can be Onsaveinstantcestate (bundle outstate) to save, but as the previous article said,Onsaveinstantcestate (bundle outstate) There is no guarantee that it will be called, because it is not a method in the activity life cycle.


5, assuming that the onsaveinstantcestate (bundle Outstate) method is called, and also save the data to the Bundle object, then when will it be taken out?

As mentioned in the 3rd above, the onsaveinstantcestate (Bundle outstate) method is called before the system enters the "non-application Behavior" to kill the activity state. The bundle object may be taken to the condition that the system does use "non-application Behavior" to kill the activity, and when the activity is to be rebuilt, the bundle object is first passed to OnCreate, and then passed to Onrestoreinstancestate (Bundle savedinstancestate) method. If the activity does not "accidentally kill" after the onsaveinstantcestate (Bundle outstate) method call, then when the activity is started again, only Onstart--onresume is called. The onrestoreinstancestate (Bundle savedinstancestate) method is not called.


Onsaveinstantcestate Example


The following shows the results of a process that the activity was recreated after it was launched into the spin screen, where a current time is saved to the bundle in the onsaveinstantcestate method, and then in the OnCreate method and The Onrestoreinstancestate method takes it out, and the bundle is empty in the OnCreate method:


Start:




After rotating the screen:




Add two buttons to Activit and let it click to jump to the second activity, unlike a button that calls the finish method when clicked, while the other does not:




Jump call the Finish () method:




Jump does not call the finish () method:




The bundle was found to be null when OnCreate was first called, and after the spin screen, the OnCreate and onrestoreinstancestate methods were given time.

The onsaveinstantcestate method is not called when the active call to finish ends the activity, but if the activity1 is not finished, it jumps directly to Activity2, The onsaveinstantcestate method is called before the onstop of the activity1.


relationship of Onsaveinstantcestate and ID in view


Well, said a lot of, seems to have not entered the focus of this article ... Here comes the following:

Above says onsaveinstantcestate method, below to see what this method actually did: (You Mei's, how is the onsaveinstantcestate method?!) Khan Σ (° °| | |) ︴, it's almost there.)


Take a look at the source code in activity:

protected void Onsaveinstancestate (Bundle outstate) {        outstate.putbundle (Window_hierarchy_tag, Mwindow.savehierarchystate ());        Parcelable p = mfragments.saveallstate ();        if (P! = null) {            outstate.putparcelable (Fragments_tag, p);        }        Getapplication (). Dispatchactivitysaveinstancestate (this, outstate);    }



There are a few things that have been done:


1, Mwindow.savehierarchystate () in the data, put into the bundle object


2. Store the state data in the fragments in the bundle object


3. Distribute the Bundle object through application Dispatchactivitysaveinstancestate.


Today this article focuses on the first question: Mwindow.savehierarchystate ()


The discovery returned is a mwindow, and this mwindow is a member variable of the window type in the Activity class:


Private Window Mwindow;


Perhaps you are already guessing this relationship between window and Phonewindow, window is an abstract class, where the Setcontentview method is an abstract method and is not implemented. Take a look at the comments of the window class:




It means: The window class has only one implementation class, that is Phonewindow.


This understand, we go to see the Phonewindow class of source code, this class we can not directly use, it is located in: Android Source directory/frameworks/base/policy/src/com/android/internal/ Policy/impl/phonewindow.java


Find the Savehierarchystate () method and let's see what it did:


 /** {@inheritDoc} */@Override public bundle Savehierarchystate () {Bundle outstate = new Bundle ();//New Bun        Dle object for holding the state if (mcontentparent = = null) {return outstate; } sparsearray<parcelable> states = new sparsearray<parcelable> ();//Create a new Sparsearray, which maintains a key array and a Valu e array, similar to map mcontentparent.savehierarchystate (states);//Call the Savehierarchystate method inside the view to save the state value to Outstate.putspa Rseparcelablearray (Views_tag, States); Stores the data in the Sparsearray in the Bundle object//Save the Focused view ID view Focusedv        Iew = Mcontentparent.findfocus ();                if (Focusedview! = null) {if (Focusedview.getid ()! = view.no_id) {//note here, if the current focus View has a set ID, it will enter the following                    Outstate.putint (Focused_id_tag, Focusedview.getid ());//Special Store the ID value of the current focus view} else {if (false) { LOG.D (TAG, "couldn ' t save which view has focus because the focused view" + Focusedview + "hasNo ID. ");}}        Save the Panels saves the panel state sparsearray<parcelable> panelstates = new sparsearray<parcelable> ();        Savepanelstate (panelstates);        if (panelstates.size () > 0) {outstate.putsparseparcelablearray (Panels_tag, panelstates); if (Mactionbar! = null) {//Save Actionbar State sparsearray<parcelable> actionbarstates = new Sparsearr            Ay<parcelable> ();            Mactionbar.savehierarchystate (actionbarstates);        Outstate.putsparseparcelablearray (Action_bar_tag, actionbarstates);    } return outstate; }


The member variable mcontentparent of the Phonewindow class is used to describe a view object of type Decorview, or a child view object of a View object of type Decorview. Used as a UI container. When its value equals null, it indicates that the view object of the application window being processed has not yet been created.


In short, as long as we set the activity to display content, whether it is a layout file or a view, it will be mounted under this mcontentparent. So in general, Mcontentparent will not be null


Well, the above has actually seen a little thing, if the ID of a focus view is not set, then the ID of the current focus view cannot be saved to the bundle object, and the focus identifier is used: Focused_id_tag this is always bright.


Let's look at what Mcontentparent.savehierarchystate (states) has done:

because: Private ViewGroup mcontentparent; is a viewgroup, and viewgroup there is no Savehierarchystate method, So the Savehierarchystate method in the view is actually called:


    public void Savehierarchystate (Sparsearray<parcelable> container) {        dispatchsaveinstancestate (container) ;    }



Look again at the Dispatchsaveinstancestate method:

    protected void Dispatchsaveinstancestate (Sparsearray<parcelable> container) {        if (MID! = no_id && ( Mviewflags & save_disabled_mask) = = 0) {//only if there is an ID can enter into the inside, add the view state            mprivateflags &= ~pflag_save_state_ called;            parcelable state = Onsaveinstancestate ();//Call View own Onsaveinstancestate method            if (Mprivateflags & Pflag_save_ state_called) = = 0) {                throw new IllegalStateException ("Derived class did not ' call                        super.onsaveinstancestate ()") ;            }            if (state = null) {                //LOG.I ("View", "Freezing #" + integer.tohexstring (MID)                //+ ":" + state);                Container.put (MID, State);}}}    


See here basically the truth, if you do not give a view to set an ID, then the activity call onsaveinstantcestate (Bundle outstate) method, there is no way to save its state, And even if it is currently in focus view, there is no way to record its focus state in the bundle object, which causes problems when the bundle state object needs to be removed.


As you can see, the state of the view is obtained by the Onsaveinstancestate () method:


   Protected Parcelable onsaveinstancestate () {        mprivateflags |= pflag_save_state_called;        return basesavedstate.empty_state;    }


Summary


1, in fact, the view default Onsaveinstancestate method does nothing, the return is an empty state, this method is a protected method, so in the view of the various subclasses, there may be different implementations, Because after all, not every view needs to save the state, and the different types of view to save the state values are not nearly the same, such as TextView may need to save the text state, and ScrollView need to save the scroll to the position value and so on.


2. We can save and remove some of the more important state values for a particular environment by customizing view, overriding the Onsaveinstancestate and Onrestoreinstancestate methods.


3, it is noteworthy that container.put (MID, State); The status value is stored by the value of the ID as the key value, so if the same view, when using the same ID, when the value of the status is taken, the problem may occur, Take a look at the Onsaveinstancestate method in ScrollView:


@Override    protected parcelable onsaveinstancestate () {        if (Mcontext.getapplicationinfo (). targetsdkversion <= Build.version_codes. JELLY_BEAN_MR2) {            //Some old apps reused IDs in ways they shouldn ' t has.            Don ' t break them, but they don ' t get the scroll state restoration.            return Super.onsaveinstancestate ();        }        Parcelable superstate = Super.onsaveinstancestate ();        savedstate ss = new savedstate (superstate);        Ss.scrollposition = mscrolly;        return SS;    }

The source code is clearly written: Some old apps reused IDs in ways they shouldn ' t has. Don ' t break them, but they don ' t get the scroll state restoration.


If you use two ScrollView in your app, and you specify the same ID, then the onsaveinstancestate will overwrite the scroll value of the previous ScrollView, causing it to be removed later. Will make the two ScrollView slide progress is always the same.


And look at the above conditions: if (Mcontext.getapplicationinfo (). targetsdkversion <= Build.version_codes. JELLY_BEAN_MR2), which means that scroll state, which was previously scrollview in 4.3 (including), is not saved, so the corresponding function can only be customized by a view inheritance ScrollView Then rewrite the onsaveinstancestate related methods.


All right, here we go today, thank you!



Please respect the original labor results, reproduced please indicate the source: http://blog.csdn.net/cyp331203/article/details/45313125 , do not allow for commercial or profit-making purposes.
















"Android Interview" (b): You can't not know the difference between view---plus ID and no ID?

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.