In the development process, if we need to register ads dynamically, we need to call the registerReceiver method to register ads dynamically. If unregisterReceiver is not called, memory leaks will result. Why?

In the Context class, registerReceiver and unregisterReceiver are both abstract methods

@Nullable public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter); /** * Unregister a previously registered BroadcastReceiver. <em>All</em> * filters that have been registeredfor this BroadcastReceiver will be
     * removed.
     *
     * @param receiver The BroadcastReceiver to unregister.
     *
     * @see #registerReceiver
     */
    public abstract void unregisterReceiver(BroadcastReceiver receiver);
Copy the code

Context’s three brothers, which I’m explaining here, open androidxref.com/7.1.2_r36/x… See the implementation of Contextimpl.java

  @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }
Copy the code

The trace code can be seen

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"); }}Copy the code

ActivityManagerNative implements dynamic registration of ads, Registration and de-registration are implemented using the Transact methods REGISTER_RECEIVER_TRANSACTION and UNREGISTER_RECEIVER_TRANSACTION of Binder (AIDL)

mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
Copy the code

Member variables in ActivityManagerNative based on the principle of observer mode, if not cancelled

 private IBinder mRemote;
Copy the code

It will hold the object forever

Another question?

There is an inner class in ActivityManagerNative