[Android]关于ContentObserver的释放

关于ContentObserver的释放

 

 

public class MainActivity extends Activity

implements OnClickListener {

 

   private static final String TAG = "MyService";

  

 

   class SettingsObserver extends ContentObserver {

       SettingsObserver(Handler handler) {

           super(handler);

       }

      

       void observe() {

          ContentResolver resolver = getContentResolver();

          resolver.registerContentObserver(

                Settings.System.getUriFor(Settings.System.ALARM_ALERT),

                false, this );

  

          updateSettings();

       }

       @Override

      public void onChange(boolean selfChange) {

          updateSettings();

       }

   }

  

   public void updateSettings() {

   }

  

   public void onClick(View src)

   {

      //2018-9-19

    

         SettingsObserver observer = new SettingsObserver(null);

         observer.observe();

     

   }

  

   @Override

   protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.fragment_main);

     

      Button aButton = (Button)findViewById(R.id.button1);

      aButton.setOnClickListener(this);   

   }

 

 

在进行注册的时候,

resolver.registerContentObserver

调用到ContentResolver的registerContentObserver方法

    public final void registerContentObserver(Uri uri, boolean notifyForDescendents,

            ContentObserver observer, int userHandle) {

        try {

            getContentService().registerContentObserver(uri, notifyForDescendents,

                    observer.getContentObserver(), userHandle);

        } catch (RemoteException e) {

        }

    }

 

里面调用到ContentObserver的getContentObserver方法

    public IContentObserver getContentObserver() {

        synchronized (mLock) {

            if (mTransport == null) {

                mTransport = new Transport(this);

            }

            return mTransport;

        }

    }

 

 

    public IContentObserver releaseContentObserver() {

        synchronized (mLock) {

            final Transport oldTransport = mTransport;

            if (oldTransport != null) {

                oldTransport.releaseContentObserver();

//解除引用

                mTransport = null;

            }

            return oldTransport;

        }

    }

new Transport(this);对ContentObserver对象进行了引用

查看这个内部类

 

    private static final class Transport extends IContentObserver.Stub {

        private ContentObserver mContentObserver;

 

        public Transport(ContentObserver contentObserver) {

            mContentObserver = contentObserver;

        }

 

        @Override

        public void onChange(boolean selfChange, Uri uri, int userId) {

            ContentObserver contentObserver = mContentObserver;

            if (contentObserver != null) {

                contentObserver.dispatchChange(selfChange, uri, userId);

            }

        }

 

        public void releaseContentObserver() {

            mContentObserver = null;

        }

    }

 

 

所以,要释放ContentObserver对象和Transport对象,必须让其解除相互引用,即需要调用Transport的releaseContentObserver方法。

ContentResolver的unregisterContentObserver就是这样操作的,里面observer.releaseContentObserver();中调用了Transport的releaseContentObserver方法。

 

    public final void unregisterContentObserver(@NonNull ContentObserver observer) {

        Preconditions.checkNotNull(observer, "observer");

        try {

//得到Transport对象,

            IContentObserver contentObserver = observer.releaseContentObserver();

            if (contentObserver != null) {

                getContentService().unregisterContentObserver(

                        contentObserver);

            }

        } catch (RemoteException e) {

        }

    }

 

所以,应当调用ContentResolver的unregisterContentObserver方法进行取消注册,同时也解除了互相引用,为finalize的调用创造前提。不然会出现泄漏。

 

猜你喜欢

转载自blog.csdn.net/aaajj/article/details/82842652