This article is the extension of Observer Pattern. In this we will try to relate this pattern with Android framework so that it would be easy for Android enthusiasts to relate better. If you are seeking for some more deep basic understanding on Observer Pattern, you can read this.
Subject or Observable | The object which is being watched. |
Class Signature | public class ContentObservable extends Observable<ContentObserver> |
Package Details | android.database.ContentObservable |
Subject or Observer | The objects which are watching the state changes. |
Class Signature | public abstract class ContentObserver extends Object. |
Package Details | android.database.ContentObserver |
Register your content observer to listen for changes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/* The Steps are below: 1) Getting Content Resolver 2) Registering Content Observer 3) Parameter 1 : The uri which you want to listen/watch Parameter 2: The second parameter indicates whether all changes to URIs that start with the given URI should trigger a method call or just changes to exactly this one URI. This can be handy for say the ContactsContract URI with its many descendants. But it can also be detrimental in that the actual change, that caused the method call, is even more obscure to you. Parameter 3: The third parameter is an instance of your ContentObserver implementation. */ getContentResolver(). registerContentObserver( SOME_URI, true, contentObserver); private ContentObserver contentObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { Log.i("technicalJungle", "boolean value is " + self); } }; |
Do not forget to unregister your content observer
1 2 3 4 5 |
// Remember general rule of thumb: Whenever you start coding registerABC() immediately also add the code to unregisterABC(). getContentResolver(). unregisterContentObserver(contentObserver); |
The URIs you can observe
Some common major examples are below:
UserDictionary.Words.CONTENT_URI
ContactsContract.Contacts.CONTENT_URI
Contacts.CONTENT_URI
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
FeedConfig.CONTENT_URI
Programming Example
As soon as any transaction on the contact db will take place like if contact will be created, deleted or modified all cases, we will get notification in MyObserver class.
So the simple steps would be
1) Need to register by getContentResolver().registerContentObserver.
2) Need to pass proper parameters, then only proper observation is possible.
3) Since ContentObserver is abstract class, so need to inherit it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class HelloActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hello); } private MyObserver contentObserver = new MyObserver(null) { @Override public void onChange(boolean self) { Log.i("technicalJungle", "boolean value is " + self); } }; @Override protected void onResume() { super.onResume(); getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contentObserver); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class MyObserver extends ContentObserver { /** * Creates a content observer. * * @param handler The handler to run {@link #onChange} on, or null if none. */ public MyObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); Log.i("technical jungle", "onChange 1 : selfChange: " + selfChange + "---- uri : " + uri); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Log.i("technical jungle", "onChange 2 : selfChange: " + selfChange); } } |
Some more examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* * The example, when runOnUiThread() and notifyDataSetChanged() * can work together with ContentObservers. * Scenario: Contact db is got some transaction and ContentObserver listen to it. */ private void initContactUpdatesReceiver() { contentObserver = new ContentObserver(null) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Log.w("technicalJungle", "Detected android contact data changed, refreshing cache"); RecipientFactory.clearCache(ConversationListActivity.this); this.runOnUiThread(new Runnable() { @Override public void run() { chattingFragment.getListAdapter().notifyDataSetChanged(); } }); } }; getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contentObserver); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* * Scenario: When any CRUD operation happened on Dictionary. Same time our class will listen to that Dictionary db change * and load the list of words again. Means refresh will be taken care. */ public UserDictionary(Context context, String locale) { super(context, Suggest.DIC_USER); mLocale = locale; // Perform a managed query. The Activity will handle closing and requerying the cursor // when needed. ContentResolver contentObserver = context.getContentResolver(); contentObserver.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { setRequiresReload(true); } }); loadDictionary(); } |
Pingback: Observer Design Pattern using Java Android - Technical Jungle