The Observer pattern for source code parsing of Android design patterns

Source: Internet
Author: User

The Observer pattern for source code parsing of Android design patterns

This article is an analysis of the observer pattern in the source parsing of Android design pattern
Android System version: 2.3
Analyst: Mr.simple, analysis Status: Not completed, reviewer: mr.simple, proofreading Status: not Started

1. Definition of Pattern Introduction mode

Defines a one-to-many dependency between objects, so that whenever an object changes state, all objects that depend on it are notified and automatically updated.

Usage Scenarios for patterns
    • The associated behavior scenario. It should be noted that the association behavior is detachable, not a "combination" relationship;
    • Event multi-level triggering scenario;
    • Cross-system message exchange scenarios, such as Message Queuing, event bus processing mechanism.
2. UML Class Diagram

Role description
    • Abstract theme (Subject) role
      Abstract theme roles keep references to all observer objects in a single aggregation (such as a ArrayList object), and each subject can have any number of observers. Abstract topics provide an interface that can add and remove observer objects, and abstract subject roles are also known as abstract Observer (Observable) roles.

    • Specific theme (ConcreteSubject) role
      The status is deposited into the specific observer object, and all registered observers are notified when the internal state of the specific subject changes. The specific subject role is also called the specific Observer (concrete Observable) role.

    • Abstract observer (Observer) role
      Define an interface for all specific observers and update yourself when you get notifications of the topic, which is called the update interface.

    • Specific observer (CONCRETEOBSERVER) role
      Stores the state of the theme from its own state. The specific observer role implements the update interface required by the abstract observer role in order to reconcile the state of itself with the state of the subject. If desired, the specific observer role can maintain a reference to a specific subject object.

3. Simple implementation of the model of the introduction of simple implementation

Androidweekly is a weekly release of the new Android technology, open Source Library, recruitment information and other content of the site, where we can see the latest technology, the most X-ray engineers, often visit this kind of website can not only broaden our horizons, but also let us access to the most foreword technology information. This is actually an RSS system, users subscribe to the Android weekly article, whenever there are updates to the new content will be pushed to subscribers. Isn't that the Observer pattern? Another name for the observer pattern is called the Publish-subscribe mode, which is the confirmation email that I subscribed to after androidweekly. Let's briefly simulate the androidweekly release process!

Realize the source code
/** * Programmer is the Observer * * @author mrsimple * * Public  class coder implements Observer {     PublicString 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     PublicStringtoString() {return "code farmer:"+ Name; }}/** * androidweekly This site is the observer, it has updated all the observers (here is the programmer) will receive the corresponding notice. * * @author mrsimple * * Public  class androidweekly extends Observable {     Public void postnewpublication(String content) {//Identity status or content changeSetchanged ();//Notify all observersNotifyobservers (content); }}//test code Public  class Test {     Public Static void Main(string[] args) {//The role being observedAndroidweekly androidweekly =NewAndroidweekly ();//ObserverCoder Mrsimple =NewCoder ("Mr.simple"); Coder Coder1 =NewCoder ("Coder-1"); Coder Coder2 =NewCoder ("Coder-2"); Coder Coder3 =NewCoder ("Coder-3");//Register the Observer with the observer list of observable objectsAndroidweekly.addobserver (mrsimple);        Androidweekly.addobserver (Coder1);        Androidweekly.addobserver (CODER2); Androidweekly.addobserver (CODER3);//Post a messageAndroidweekly.postnewpublication ("The new issue androidweekly come!"); }}

Input Result:

Hi,Coder-3,androidweeklyUpdated, Content: new issueandroidweeklyCome on!Hi,Coder-2,androidweeklyUpdated, Content: new issueandroidweeklyCome on!Hi,Coder-1,androidweeklyUpdated, Content: new issueandroidweeklyCome on!Hi,Mr. Simple,androidweeklyUpdated, Content: new issueandroidweeklyCome on!

You can see that all users subscribed to androidweekly have been updated, and a one-to-many subscription-publishing system is as simple as that.

Here observer is the abstract observer role, coder plays the role of the specific observer, observable corresponds to the abstract subject role, androidweekly is the specific theme role. Coder is a specific observer, they subscribe to androidweekly, a specific observable, and when the androidweekly is updated, it iterates through all the observers (this is the coder Code Farm), and then publishes an updated message to the observers. That is, call the Update method in coder, so that the 1-to-many notification function is reached. Both observer and observable are already built into the JDK, which shows the importance of the observer pattern in Java.

Mode implementation in Android source code

The ListView is the most important control in Android and does not have one. And the most important point of the ListView is Adapter, in the Android design mode source parsing adapter (Adapter) mode we analyzed the Adapter mode, after we add data to the ListView, we will call a method: Notifydatasetchanged (), what is this for? Today we are going to unveil its mystery.

The first step is to follow up on this method notifydatasetchanged method, which is defined in Baseadapter with the following code:

 Public Abstract  class baseadapter implements listadapter, spinneradapter {    //Data Set Viewer    Private FinalDatasetobservable mdatasetobservable =NewDatasetobservable ();//Code omission     Public void Registerdatasetobserver(Datasetobserver observer)    {MDATASETOBSERVABLE.REGISTEROBSERVER (Observer); } Public void Unregisterdatasetobserver(Datasetobserver observer)    {MDATASETOBSERVABLE.UNREGISTEROBSERVER (Observer); }/** * Notifies the attached observers that the underlying data have been changed * and any View reflecting the     Data set should refresh itself. * Notify all observers when data sets are changed */     Public void notifydatasetchanged() {mdatasetobservable.notifychanged (); }}

We look at Baseadapter the above code, there is a general understanding that the original Baseadapter is an observer mode!
So how does the baseadapter work? What are these observers? Let's take a step-by-step analysis.

Let's take a look at the mdatasetobservable.notifychanged () function first.

/** * A specialization of Observable for Datasetobserver, provides methods for * Invoking the various callback met Hods of Datasetobserver. */Public class datasetobservable extends Observable<datasetobserver > {    /** * Invokes onChanged on each observer.     Called when the data set being observed have * changed, and which when read contains the new state of the data. */public void notifychanged () {synchronized (mobservers) {//Call all observers in onchanged mode             for(int i = mobservers.size ()-1; I >=0;            i--) {mobservers.get (i). onChanged (); }        }    }//Code omission}

Well, the code is simple, which is to traverse all the observers in mdatasetobservable.notifychanged () and invoke their OnChanged method.

So where do these observers come from? First the ListView uses the Setadapter method to set the adapter, and we look at the relevant code.

    @Override     Public void Setadapter(ListAdapter adapter) {//If you already have a adapter, log out of the adapter corresponding observer first        if(Madapter! =NULL&& Mdatasetobserver! =NULL) {madapter.unregisterdatasetobserver (mdatasetobserver); }//Code omission        Super. Setadapter (adapter);if(Madapter! =NULL) {mareallitemsselectable = madapter.areallitemsenabled (); Molditemcount = Mitemcount;//Get the number of dataMitemcount = Madapter.getcount (); Checkfocus ();//Note here: Create a data set observerMdatasetobserver =NewAdapterdatasetobserver ();//Register this observer with adapter and actually register it in datasetobservableMadapter.registerdatasetobserver (Mdatasetobserver);//Code omission}Else{//Code omission} requestlayout (); }

You can see that a adapterdatasetobserver is built when you set up adapter, which is not the observer we mentioned above, and finally registers this observer with adapter so that our observers and observers have it. In general, our data sets are put into adapter, for example:

public   Abstract  class      Useradapter  extends  baseadapter  {    //data set  protected     list<string> Mdataset = new  linkedlist<string> (); protected     Context Mcontext = null ; public  commonadapter  (context context, list<string> DataSet)        {this . Mdataset = DataSet;    this . Mcontext = context; }}

Maybe you're a little dizzy by this time? What is Adapterdatasetobserver? How does it work? So I'll take a look at Adapterdatasetobserver first.

Adapterdatasetobserver is defined in the parent class Abslistview of the ListView, with the following code:

     class adapterdatasetobserver extends adapterview<listadapter . Adapterdatasetobserver {@Override Public voidOnChanged () {Super. onChanged ();if(Mfastscroller! =NULL) {mfastscroller.onsectionschanged (); }} @Override Public voidOninvalidated () {Super. oninvalidated ();if(Mfastscroller! =NULL) {mfastscroller.onsectionschanged (); }        }    }

It is adapterdatasetobserver by the parent class that inherits from Abslistview, the code is as follows: Adapterview

     class adapterdatasetobserver extends datasetobserver {        PrivateParcelable minstancestate =NULL;//As noted above, the OnChanged method of all observers is invoked when calling adapter's notifydatasetchanged, and the core implementation is here@Override Public voidOnChanged () {mdatachanged =true; Molditemcount = Mitemcount;//Get the number of data in adapterMitemcount = Getadapter (). GetCount ();//Detect The case where a cursor that is previously 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 ();//re-layout Adapterview components such as ListView, GridView, etc.Requestlayout (); }//Code omission         Public voidClearsavedstate () {minstancestate =NULL; }    }

Here we know, when the data of the ListView changes, call adapter's notifydatasetchanged function, this function will call datasetobservable notifychanged function, This function invokes the OnChanged method of all observers (Adapterdatasetobserver). This is an observer pattern!

Finally, let's go through the Adapterview with an inner class adapterdatasetobserver that builds a adapterdatasetobserver when the ListView is set adapter and registered in the adapter, this is an observer. The adapter contains a dataset observer, Datasetobservable, which the developer calls adapternotifydatasetchanged manually when the number of data is changed. Notifydatasetchanged actually calls Datasetobservable's notifychanged function, which iterates through the onchanged functions of all observers. In Adapterdatasetobserver's onchanged function, you get a new number of datasets in adapter, and then call the ListView's Requestlayout () method to re-layout and update the user interface.

Figure 1 Figure 2

This article from Saos Open Source project group, about Saos Introduction please refer to the Android Open Source Library and design mode open Source group Saos, more articles please go to Saos Open Source project group;

4. Talk

The ListView uses adapter and observer patterns to make scalability, flexibility, and low coupling, which I think is a good example of how design patterns are used in Android source code. So why do Android architects design a ListView like this, and how do they achieve low coupling and high flexibility? This is for everyone to think about, if there is time for me to share my views.

Advantages
    • An abstract coupling between the observer and the observed person
Disadvantages
    • The observer pattern needs to consider the development efficiency and the operational efficiency problem, an observer, multiple observers, development and debugging will be more complex, and in Java message notification by default is sequential execution, an observer jam, will affect the overall efficiency of execution. In this case, the asynchronous approach is generally considered.

The Observer pattern for source code parsing of Android design patterns

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.