Best practices of observer mode on android

Source: Internet
Author: User
Tags notification center

Best practices of observer mode on android

 

In the previous article, I introduced the definition and some basic concepts of the observer mode. The observer mode is widely used in android development, such as monitoring and broadcasting of android button events, it can be used in any mode similar to news-subscription. In a sense, android is a bit like a java ee web page. You must provide a View layer for operations, it is very troublesome to transmit data to send notifications between multiple pages.

In android, the page B is redirected from page A to page B. After performing some operations on page B, we need to notify page A to refresh the data. We can call page B through startActivityForResult, after page B ends, rewrite onActivityResult on page A to receive the returned result and refresh the page. However, if the jump path is A-> B-> C-> ....., if you use this method to refresh A on pages after C or C, it will be very tricky. Using this method may have the following drawbacks:

  1. 1. It is very difficult to transfer multiple paths or events.2. Data is not updated in a timely manner. Users often need to wait to reduce system performance and user experience.3. The code structure is chaotic and difficult to encode and expand.

    Therefore, we consider using the observer mode to solve this problem.

    1. determine requirements

    In the APP, we have some settings. We hope that after the settings are complete, we can immediately respond to the homepage, for example, clearing chat records on QQ, we hope that it will be automatically cleared after we set it back to the home page. Some people may think this is a very simple thing and think it is better to read the cache directly on the home page, what is in the cache? This solution has two problems:

    • When to read the cache? Will it be refreshed every time I return to the home page? This will consume too much resources and the user experience will be poor.
    • Data cannot be refreshed locally.

      Therefore, the main requirements of the line function and code structure are as follows:

      1. 1. You can directly notify other pages that have listened to this event to refresh immediately after some pages are configured, without the need to refresh them when you return to some pages.2. Identify the Event Notifications and process different events.3. dynamically scaling event types allows callers to quickly register and listen to events.Ii. System Design

        From the previous article, we know that a complete observer mode requires these objects:

        1. Subject abstract topic role: This is the abstract object to be observed. It stores the reference list of all observer objects and provides the registration and anti-registration functions.The specific topic role of ConcreteSubject: stores the relevant status into each ConcreteObserver object and sends a notification to each observer when its status is changed.Observer abstract Observer: defines an interface for all specific observers and updates themselves when notified.ConcreteObserver specific Observer: maintain a reference pointing to the ConcreteObserver object and store the relevant status. These statuses should be consistent with the target status. The interface for updating the Observer is consistent with the target status.

          For android, we need to design one by oneAbstract BaseObserverActivitySo that all Activity pages can inherit it. In essence, all the activities that inherit this class are an observer, then, the observer object defines the types of events to be monitored and processes the events accordingly.

          Iii. Specific implementation scheme

          (1) EventSubjectInterface: Abstract topic Role Implementation

          /*** Abstract topic role * @ author zhiwu_yan * @ since April 06, 2015 * @ version 1.0 */public interface EventSubjectInterface {/*** register the observer * @ param observer */public void registerObserver (EventObserver observer ); /*** unregister the observer * @ param observer */public void removeObserver (EventObserver observer ); /*** notify the registered observer to update the data or UI */public void yyobserver (String eventType );}

          It mainly includes the observer registration method and the anti-registration method as well as the method for notifying the observer to update the UI. Let's take a look at the specific implementation.

          (2) EventSubject: implementation of a specific topic role

          /*** The implementation of the specific theme role, which is used to monitor the occurrence of events, implement * @ author zhiwu_yan * @ since April 06, 2015 * @ version 1.0 */public class EventSubject implements EventSubjectInterface {private List
                   
                    
          MEventObservers = new ArrayList
                    
                     
          (); Private static volatile EventSubject mEventSubject; private EventSubject () {} public synchronized static EventSubject getInstance () {if (mEventSubject = null) {mEventSubject = new EventSubject ();} return mEventSubject;} @ Override public void registerObserver (EventObserver observer) {synchronized (mEventObservers) {if (observer! = Null) {if (mEventObservers. contains (observer) {return;} mEventObservers. add (observer) ;}}@ Override public void removeObserver (EventObserver observer) {synchronized (mEventObservers) {int index = mEventObservers. indexOf (observer); if (index> = 0) {mEventObservers. remove (observer) ;}}@ Override public void policyobserver (String eventType) {if (mEventObservers! = Null & mEventObservers. size ()> 0 & eventType! = Null) {for (EventObserver observer: mEventObservers) {observer. dispatchChange (eventType );}}}}
                    
                   

          Note that the singleton mode is used to control only one topic role, which stores allThe EventObserver list,That is, the list of Nurses (see the previous chapter). It is worth mentioning that synchronized is used to control multi-thread operations.

          (3) EventObserverInterface: Abstract observer object

          /*** Observer interface ** @ author zhiwu_yan * @ since April 06, 2015 * @ version 1.0 */public interface EventObserverInterface {/*** update data or UI Based on the event * @ param eventType */public void dispatchChange (String eventType );}

          There is only one method to follow the new UI Based on the event type. Let's look at the specific abstract observer.

          (4) EventObserver: Specifies the audience member.

          /*** Is used to update the UI. Here, the onChange Method for updating the UI * @ author zhiwu_yan * @ since April 06, 2015 * @ version 1.0 */public abstract class EventObserver implements EventObserverInterface {private Handler mHandler; public EventObserver () {mHandler = new Handler (logoff. getMainLooper ();} public abstract void onChange (String eventType); @ Override public void dispatchChange (String eventType) {mHandler. post (new NotificationRunnable (eventType);} private final class icationicationrunnable implements Runnable {private String mEventType; public NotificationRunnable (String eventType) {this. mEventType = eventType;} @ Override public void run () {EventObserver. this. onChange (mEventType );}}}

          We define an abstract onChange method to be implemented by sub-classes. This method is used to process corresponding event types, such as data needs to be refreshed. Because mHandler. post is used with the new UI thread, if it is a time-consuming operation, it needs to be processed by another thread.

          (5) As mentioned earlier, in Android, we need to define a BaseActivity with the observer mode to be used by some businesses that need to be monitored, in this way, all the activities inherited are specific observer objects.

          /*** An Activity with the observer mode is essentially an Observer * @ author zhiwu_yan * @ since at on May 25 * @ version 1.0 */public abstract class BaseObserverActivity extends ActionBarActivity {private ActivityEventObserver mActivityEventObserver; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); mActivityEventObserver = new ActivityEventObserver (this); registerObserver (mActivity EventObserver) ;}@ Override protected void onDestroy () {super. onDestroy (); removeObserver (mActivityEventObserver);} public void registerObserver (EventObserver observer) {final String [] observerEventTypes = getObserverEventType (); // obtain all the business types to be monitored if (observerEventTypes! = Null & observerEventTypes. length> 0) {final EventSubject eventSubject = EventSubject. getInstance (); eventSubject. registerObserver (observer) ;}} public void removeObserver (EventObserver observer) {final String [] observerEventTypes = getObserverEventType (); // obtain all the business types to be monitored if (observerEventTypes! = Null & observerEventTypes. length> 0) {final EventSubject eventSubject = EventSubject. getInstance (); eventSubject. removeObserver (observer) ;}}/*** this method is called in a specific observer object. You can update the corresponding UI Based on the event type, this method is called in the UI thread. * therefore, time-consuming operations cannot be performed in this method, you can also open the thread * @ param eventType event type */protected abstract void onChange (String eventType ); /*** use this method to tell the specific service type that the observer needs to listen to * @ return */protected abstract String [] getObserverEventType (); private static class ActivityEventObserver extends EventObserver {// Add weak references to prevent private final WeakReference objects from being recycled
                   
                    
          MActivity; public ActivityEventObserver (BaseObserverActivity) {super (); mActivity = new WeakReference
                    
                     
          (Activity) ;}@ Override public void onChange (String eventType) {BaseObserverActivity = mActivity. get (); if (activity! = Null) {activity. onChange (eventType );}}}}
                    
                   

          In addition, we need to define an event type that can be dynamically expanded: EventType

          /*** Write all business types here to facilitate management * @ author zhiwu_yan * @ since April 06, 2015 * @ version 1.0 */public class EventType {private static volatile EventType mEventType; private final static Set
                   
                    
                     
                      
                       
                        
          EventsTypes = new HashSet
                        
                          (); Public final static String UPDATE_MAIN = com. updateMain; public final static String UPDATE_Text = com. updateText; private EventType () {eventsTypes. add (UPDATE_MAIN); eventsTypes. add (UPDATE_Text);} public static EventType getInstance () {if (mEventType = null) {mEventType = new EventType () ;}return mEventType;} public boolean contains (String eventType) {return eventsTypes. contains (eventType );}}
                        
                       
                      
                     
                    
                   

          Here I mainly define two event types. If you need to define N event types, you just need to add the events you need to define to the event class table.

          To update a page, you only need to call the following method:

          EventSubject eventSubject=EventSubject.getInstance();        EventType eventTypes=EventType.getInstance();        if(eventTypes.contains(eventType)){            eventSubject.notifyObserver(eventType);        }

          To facilitate management, we also create a new tool class:

          /*** The notification center is used to notify the updated data or UI, single Sample mode * @ author zhiwu_yan * @ since April 6, 2015 * @ version 1.0 */public class policy {private static volatile policy mNotify; private Policy () {} public static policy getInstance () {if (mNotify = null) {mNotify = new Notify ();} return mNotify;} public void NotifyActivity (String eventType) {EventSubject eventSubject = EventSubject. getInstance (); EventType eventTypes = EventType. getInstance (); if (eventTypes. contains (eventType) {eventSubject. notifyObserver (eventType );}}}

          The basic framework is complete here. Let's see how to use it.

          Iv. Usage

          Define A page: MainActivity. This page is an observer who needs to listen to some notifications from other pages. Once there is a modification, it will be handled differently based on the corresponding events:

          Public class MainActivity extends BaseObserverActivity {private TextView mLableTv; private ImageView mPicIv; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); mLableTv = (TextView) findViewById (R. id. label_ TV); mPicIv = (ImageView) findViewById (R. id. pic_iv) ;}@ Override public boolean onCreateOptionsMenu (Menu menu) {getMenuInflater (). inflate (R. menu. menu_main, menu); return true;} @ Override public boolean onOptionsItemSelected (MenuItem item) {int id = item. getItemId (); switch (id) {case R. id. go_other_activity: goActivity (OtherActivity. class); return true;} return super. onOptionsItemSelected (item);} private void goActivity (Class
                   Activity) {Intent intent = new Intent (this, activity); startActivity (intent) ;}@ Override protected void onChange (String eventType) {if (EventType. UPDATE_MAIN = eventType) {mPicIv. setImageResource (R. mipmap. pic_two);} else if (EventType. UPDATE_Text = eventType) {mLableTv. setText (image updated); }}@ Override protected String [] getObserverEventType () {return new String [] {EventType. UPDATE_MAIN, EventType. UPDATE_Text };}@ Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {super. onActivityResult (requestCode, resultCode, data); startActivityForResult ();}}

          The onChange method updates different images based on the event type. In getObserverEventType (), we define the business type that the observer needs to observe, other business types are ignored.

          Our B page: that is, the page for sending notifications. The setting page on the APP only serves to notify the observer:

          public class OtherActivity extends ActionBarActivity {    private Button mUpdateBtn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.other_activity);        mUpdateBtn=(Button) findViewById(R.id.update_edit_btn);        mUpdateBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Notify.getInstance().NotifyActivity(EventType.UPDATE_Text);                Notify.getInstance().NotifyActivity(EventType.UPDATE_MAIN);            }        });    }}

           

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.