[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的呼叫創造前提。不然會出現洩漏。