Android Design Pattern source code parsing: ListView observer pattern, androidlistview

Source: Internet
Author: User

Android Design Pattern source code parsing: ListView observer pattern, androidlistview
Android Design Pattern source code parsing-Observer Pattern

This article analyzes the observer mode in the source code parsing of Android Design Patterns
Android: 2.3
ANALYST: Mr. Simple, analysis status: incomplete, Proofreader: Mr. Simple, proofreader Status: Not started

1. Introduction to Schema Definition

Defines a one-to-many dependency between objects, so that every time an object changes state, all objects dependent on it will be notified and automatically updated.

Application scenarios
  • Associated behavior scenarios. It should be noted that association behaviors can be split rather than "combined" relationships;
  • Multi-level event triggering scenarios;
  • Cross-system message exchange scenarios, such as message queues and event bus processing mechanisms.
2. UML class diagram

Roles
  • Abstract topic role
    Abstract topic roles store reference of all observer objects in a aggregation (such as an ArrayList object). Each topic can have any number of observers. Abstract topic provides an interface to add and delete observer objects. Abstract topic roles are also called abstract observer roles.

  • ConcreteSubject role
    Stores the status in a specific observer object. When the internal status of a specific subject changes, a notification is sent to all registered observers. A topic role is also called a Concrete Observable role.

  • Abstract Observer (Observer) Role
    Define an interface for all the specific observers to update themselves when they receive notifications of the topic. This interface is called the update interface.

  • ConcreteObserver role
    The storage status is the same as that of the topic. The specific observer role implements the update interface required by the abstract observer role to coordinate its status with the status of the topic. If necessary, a specific observer role can maintain a reference pointing to a specific topic object.

3. Introduction to simple implementation of the Mode

AndroidWeekly is a weekly website that publishes content about new Android technologies, open-source libraries, and recruitment information. Here we can see the latest technology and the best engineer, frequent visits to such websites not only broaden our horizons, but also give us access to the most advanced technology information. This is actually an RSS system. Users subscribe to Android Weekly articles and push new content to subscribed users whenever there is an update. Isn't that the observer mode? The observer mode is also called the publish-subscribe mode, which is the confirmation email sent by them after I subscribe to AndroidWeekly. Let's simulate the release process of AndroidWeekly!

Source code
/*** The programmer is the Observer ** @ author mrsimple */public class Coder implements Observer {public String name; public Coder (String aName) {name = aName ;} @ Override public void update (Observable o, Object arg) {System. out. println ("Hi," + name + ", AndroidWeekly updated, content:" + arg) ;}@ Override public String toString () {return "codenong: "+ name ;}/ *** the website AndroidWeekly is an observer. It updates all the observers (programmers here) and receives corresponding notifications. ** @ Author mrsimple */public class AndroidWeekly extends Observable {public void postNewPublication (String content) {// setChanged () when the identity status or content is changed (); // notify all observers of policyobservers (content) ;}// Test code public class Test {public static void main (String [] args) {// AndroidWeekly androidWeekly = new AndroidWeekly (); // observer Coder mrsimple = new Coder ("mr. simple "); Coder coder1 = new Coder (" coder-1 "); Coder coder2 = new Coder ("coder-2"); Coder coder3 = new Coder ("coder-3 "); // register the observer to androidWeekly in The Observer list of the observed object. addObserver (mrsimple); androidWeekly. addObserver (coder1); androidWeekly. addObserver (coder2); androidWeekly. addObserver (coder3); // publishes the message androidWeekly. postNewPublication ("the new AndroidWeekly is coming! ");}}

Input result:

Hi, coder-3, AndroidWeekly updated. Content: AndroidWeekly is coming! Hi, coder-2, AndroidWeekly updated. Content: AndroidWeekly is coming! Hi, coder-1, AndroidWeekly updated. Content: AndroidWeekly is coming! Hi, mr. simple, AndroidWeekly updated. Content: AndroidWeekly is coming!

We can see that all users that have subscribed to AndroidWeekly have received update messages. The one-to-many subscription-publishing system is just as simple as that.

Here, the Observer is an abstract Observer role. The Coder assumes the role of a specific Observer; the Observable corresponds to the abstract topic role, and AndroidWeekly refers to the specific topic role. Coder is a specific observer. they subscribe to the specific observability object AndroidWeekly. When AndroidWeekly is updated, it will traverse all the observers (here it is Coder coders ), then, send an updated message to the observer, that is, call the update method in the Coder, which achieves the one-to-many notification function. Both Observer and Observable are built in jdk, which shows the importance of Observer mode in java.

Mode implementation in Android source code

ListView is one of the most important controls in Android. The most important aspect of ListView is the Adapter. In the Adapter mode of Android design mode source code parsing, we analyzed the Adapter mode. After we add data to the ListView, we will call a method called yydatasetchanged (). Why? Today we will unveil its secrets.

The first step is to follow up the notifyDataSetChanged method, which is defined in BaseAdapter and the code is as follows:

Public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {// dataset observer private final DataSetObservable mDataSetObservable = new DataSetObservable (); // The Code omitting public void observer (DataSetObserver observer) {mDataSetObservable. registerObserver (observer);} public void unregisterDataSetObserver (DataSetObserver observer) {mDataSetObservable. unregisterObserver (observer);}/*** Notifies the attached observers that the underlying data has been changed * and any View reflecting the data set shocould refresh itself. * notify all observers when the dataset is changed */public void notifyDataSetChanged () {mDataSetObservable. notifyChanged ();}}

Let's take a look at the above BaseAdapter code. We have a general understanding that the original BaseAdapter is an observer mode!
So how does BaseAdapter work? What are these observers? We will analyze it step by step.

Let's take a look at the mDataSetObservable. policychanged () function.

/*** A specialization of Observable for DataSetObserver that provides methods for * invoking the various callback methods of DataSetObserver. */public class DataSetObservable extends Observable <DataSetObserver> {/*** Invokes onChanged on each observer. called when the data set being observed has * changed, and which when read contains the new state of the data. */public void policychanged () {synchronized (mObservers) {// call the onChanged method of all observers for (int I = mObservers. size ()-1; I> = 0; I --) {mObservers. get (I ). onChanged () ;}}// Code omitted}

Well, the code is very simple, that is, traverse all the observers in mDataSetObservable. notifyChanged () and call their onChanged method.

So where do these observers come from? First, ListView uses the setAdapter method to set the Adapter. Let's look at the relevant code.

@ Override public void setAdapter (ListAdapter adapter) {// if an adapter already exists, first cancel the observer if (mAdapter! = Null & mDataSetObserver! = Null) {mAdapter. unregisterDataSetObserver (mDataSetObserver);} // The Code omitting super. setAdapter (adapter); if (mAdapter! = Null) {mAreAllItemsSelectable = mAdapter. areAllItemsEnabled (); mOldItemCount = mItemCount; // The number of data retrieved. mItemCount = mAdapter. getCount (); checkFocus (); // note here: Create a dataset observer mDataSetObserver = new AdapterDataSetObserver (); // register the observer to the Adapter, it is actually registering mAdapter in DataSetObservable. registerDataSetObserver (mDataSetObserver); // Code omitted} else {// Code omitted} requestLayout ();}

We can see that an AdapterDataSetObserver will be built when the Adapter is set. Isn't that the Observer we mentioned above? register the Observer into the adapter, so that our observer and observer will have it. Generally, our data assembly is placed in the Adapter, for example:

Public abstract class UserAdapter extends BaseAdapter {// dataset protected List <String> mDataSet = new dataset List <String> (); protected Context mContext = null; public CommonAdapter (Context context, list <String> dataSet) {this. mDataSet = dataSet; this. mContext = context ;}}

Maybe you are a little dizzy at this time? What is AdapterDataSetObserver? How does it work? So let's take a look at AdapterDataSetObserver.

AdapterDataSetObserver is defined in the parent class AbsListView of ListView. The Code is as follows:

    class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {        @Override        public void onChanged() {            super.onChanged();            if (mFastScroller != null) {                mFastScroller.onSectionsChanged();            }        }        @Override        public void onInvalidated() {            super.onInvalidated();            if (mFastScroller != null) {                mFastScroller.onSectionsChanged();            }        }    }

It is the AdapterDataSetObserver of the parent class AdapterView inherited from AbsListView. The Code is as follows:

Class AdapterDataSetObserver extends DataSetObserver {private Parcelable mInstanceState = null; // As mentioned above, the onChanged method of all observers is called when the notifyDataSetChanged method of the Adapter is called, the core implementation is here @ Override public void onChanged () {mDataChanged = true; mOldItemCount = mItemCount; // obtain the number of data in the Adapter, mItemCount = getAdapter (). getCount (); // Detect the case where a cursor that was previusly invalidated has // been repopulated With new data. if (AdapterView. this. getAdapter (). hasStableIds () & mInstanceState! = Null & mOldItemCount = 0 & mItemCount> 0) {AdapterView. this. onRestoreInstanceState (mInstanceState); mInstanceState = null;} else {rememberSyncState ();} checkFocus (); // relayout the AdapterView components such as ListView and GridView ();} // The Code omitting public void clearSavedState () {mInstanceState = null ;}}

Now we know that when the ListView data changes, the notifyDataSetChanged function is called by the Adapter. This function then calls the notifyChanged function of DataSetObservable, which calls all the observers (AdapterDataSetObserver) onChanged method. This is an observer mode!

Finally, let's continue with the preview. AdapterView has an internal class AdapterDataSetObserver. When the ListView sets the Adapter, it constructs an AdapterDataSetObserver and registers it to the Adapter. This is an observer. The Adapter contains a dataset that can be used to observe DataSetObservable. When the data volume changes, the developer manually calls adapterpolicydatasetchanged. notifyDataSetChanged actually calls the notifyChanged function of DataSetObservable, this function traverses all observer onChanged functions. In the onChanged function of AdapterDataSetObserver, the new number of datasets in the Adapter is obtained, and then the layout is refreshed by calling the requestLayout () method of ListView to update the user interface.

Figure 1 Figure 2

This article is from the SAOS open-source project team. For more information about SAOS, see the open-source Android library and design mode open-source group SAOS. For more information, see the SAOS open-source project team;

4. Miscellaneous

ListView mainly uses the Adapter and observer modes to make the scalability and flexibility very strong, while the coupling degree is very low. This is a good example of the design mode in the Android source code. So why do Android architects design ListView in this way to achieve low coupling and high flexibility? Let us think about this. If you have time, I will share my views.

Advantages
  • Abstract coupling between the observer and the observer
Disadvantages
  • In the observer mode, you need to consider the development efficiency and running efficiency issues. When one observer and multiple observers are involved, the development and debugging will be complicated, and the notifications of messages in Java are executed sequentially by default, the jamming of an observer will affect the overall execution efficiency. In this case, asynchronous mode is generally considered.

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.