开发过程中,如果需要动态注册广告,我们需要调用registerReceiver方法实现动态注册广告,如果没有调用unregisterReceiver会导致内存泄漏,这是为什么呢?
以Context类来说,registerReceiver和unregisterReceiver都是2个abstract方法
@Nullable
public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
IntentFilter filter);
/**
* Unregister a previously registered BroadcastReceiver.(注销先前注册过的BroadcastReceiver) All
* filters that have been registered for this BroadcastReceiver will be
* removed.
*
* @param receiver The BroadcastReceiver to unregister.
*
* @see #registerReceiver
*/
public abstract void unregisterReceiver(BroadcastReceiver receiver);
Context的三兄弟关系,我就在这里解说了,打开
http://androidxref.com/7.1.2_r36/xref/frameworks/base/core/java/android/app/ContextImpl.java
查看ContextImpl.java的实现
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
在跟踪代码可以看到
ActivityManagerNative.getDefault().registerReceiver(mMainThread.getApplicationThread(), mBasePackageName,rd, filter, broadcastPermission, userId);
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
if (mPackageInfo != null) {
IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
getOuterContext(), receiver);
try {
ActivityManagerNative.getDefault().unregisterReceiver(rd);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} else {
throw new RuntimeException("Not supported in system context");
}
}
ActivityManagerNative实现动态注册广告,利用binder(AIDL)的transact方法REGISTER_RECEIVER_TRANSACTION和UNREGISTER_RECEIVER_TRANSACTION实现注册和反注册
mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
基于观察者模式的原理,如果不取消的话,在ActivityManagerNative的成员变量
private IBinder mRemote;
就会一直持有对象
另外一个问题?