关于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的调用创造前提。不然会出现泄漏。