// Contentobserver only notifies the database of changes in content
Cursor. registercontentobserver (mchangeobserver );
// Datasetobserver notifies the upper-layer cursor that the data content has been updated after calling requery.
Cursor. registerdatasetobserver (mdatasetobserver );
The calling process is as follows:
When we use getcontentresolver (). Query (), our resolver will find the corresponding provider through Uri and call the corresponding query () method,
Part of this method:
Sqlitedatabase DB = mopenhelper. getreadabledatabase ();
Cursor ret = QB. Query (dB, projection, selection, selectionargs, null, null, finalsortorder );
// Todo: does this need to be a URI for this provider.
Ret. setnotificationuri (getcontext (). getcontentresolver (), Uri );
Return ret;
Cursor itself is only an interface. actually called is abstractcursor.
Public void setnotificationuri (contentresolver Cr, Uri policyuri ){
Synchronized (mselfobserverlock ){
Mpolicyuri = policyuri;
Mcontentresolver = CR;
If (mselfobserver! = NULL ){
Mcontentresolver. unregistercontentobserver (mselfobserver );
}
Mselfobserver = new selfcontentobserver (this );
Mcontentresolver. registercontentobserver (mpolicyuri, true, mselfobserver );
Mselfobserverregistered = true;
}
}
// Internal class of abstractcursor
Protected static class selfcontentobserver extends contentobserver {
Weakreference <abstractcursor> mcursor;
Public selfcontentobserver (abstractcursor cursor ){
Super (null );
Mcursor = new weakreference <abstractcursor> (cursor );
}
@ Override
Public Boolean deliverselfnotifications (){
Return false;
}
@ Override
Public void onchange (Boolean selfchange ){
Abstractcursor cursor = mcursor. Get ();
If (cursor! = NULL ){
Cursor. onchange (false );
}
}
}
Contentobservable mcontentobservable = new contentobservable (); // contentobservable held by abstractcursor
// Onchange () of abstractcursor ()
Protected void onchange (Boolean selfchange ){
Synchronized (mselfobserverlock ){
Mcontentobservable. dispatchchange (selfchange );
If (mpolicyuri! = NULL & selfchange ){
Mcontentresolver. policychange (mpolicyuri, mselfobserver); // selfchange = false
}
}
}
In abstractcursor
Public void registercontentobserver (contentobserver observer ){
Mcontentobservable. registerobserver (observer );
}
In contentobservable
Public void dispatchchange (Boolean selfchange ){
Synchronized (mobservers ){
For (contentobserver observer: mobservers ){
If (! Selfchange | observer. deliverselfications ications ()){
Observer. dispatchchange (selfchange );
}
}
}
}
In cursoradapter, we registered contentobserver.
Private class changeobserver extends contentobserver {
Public changeobserver (){
Super (new handler ());
}
@ Override
Public Boolean deliverselfnotifications (){
Return true;
}
@ Override
Public void onchange (Boolean selfchange ){
Oncontentchanged ();
}
}
// Method of the parent class
Public final void dispatchchange (Boolean selfchange ){
If (mhandler = NULL ){
Onchange (selfchange );
} Else {
Mhandler. Post (New notificationrunnable (selfchange ));
}
}
// Internal class of the parent class
Private final class icationicationrunnable implements runnable {
Private Boolean mself;
Public notificationrunnable (Boolean self ){
Mself = self;
}
Public void run (){
Contentobserver. This. onchange (mself );
}
}
In cursoradapter
Protected void oncontentchanged (){
If (mautorequery & mcursor! = NULL &&! Mcursor. isclosed ()){
If (config. logv) log. V ("cursor", "auto requerying" + mcursor + "due to update ");
Mdatavalid = mcursor. requery ();
}
}
In abstractcursor
Public Boolean requery (){
If (mselfobserver! = NULL & mselfobserverregistered = false ){
Mcontentresolver. registercontentobserver (mpolicyuri, true, mselfobserver );
Mselfobserverregistered = true;
}
Mdatasetobservable. policychanged (); // any cursor that inherits abstractcursor will execute this sentence by calling super. requery ().
Return true;
}
If we have registered the dataset observer, we will be notified accordingly.
Summary:
Contentobserver is an advance notification. At this time, it only notifies cursor that my content has changed.
Datasetobserver is a post-notification. This notification can be obtained only when the requery () deactivate () Close () method is called.
Therefore, the most important thing is contentobserver, which tells you that the database has changed. Of course, if you want to do something after updating the data set of cursor
Datasetobserver is also required.
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/yangxinle137/archive/2010/11/03/5985515.aspx