Android DeathRecipient & RemoteCallbackList

6 篇文章 0 订阅
DeathRecipient

DeathRecipient类的作用,当Binder服务端程序挂掉了,通知给Binder客户端程序,binder服务端程序挂掉后,kernel会调用binder_release函数,发送死亡通知给绑定的Binder代理对象

public interface DeathRecipient {
    public void binderDied();
}
Android系统中的使用案列
public final class ActivityManagerService {
    private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
       
        //创建IBinder.DeathRecipient子类对象
        AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
        //建立binder死亡回调
        thread.asBinder().linkToDeath(adr, 0);
        
    }

    private final class AppDeathRecipient implements IBinder.DeathRecipient {
        
        public void binderDied() {
            synchronized(ActivityManagerService.this) {
                appDiedLocked(mApp, mPid, mAppThread, true);
            }
        }
    }
}
自定义服务中的使用案列
final IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
    @Override
    public void binderDied() {
        // 服务器进程死亡
        Log.d(TAG, "binderDied");
    }
};

ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, final IBinder service) {
        mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        if (mIMyAidlInterface != null) {
                try {
                    // 建立binder死亡回调,当自定义服务进程挂掉后,回调DeathRecipient的binderDied函数
                    mIMyAidlInterface.asBinder().linkToDeath(deathRecipient, 0);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
        }
    }
}


    @Override
    public void onServiceDisconnected(ComponentName name) {
        mIMyAidlInterface = null;
    }
};

bindService(new Intent(this, MyService.class), connection, Context.BIND_AUTO_CREATE);
linkToDeath

Binder的实现为空实现,因为服务端进程自己挂没有挂,自己最清楚, 不需要来注册函数,就算linkToDeath函数能注册,服务端进程挂掉后,linkToDeath函数也没有机会执行了,死亡通知是为了BinderProxy对象则需要知道服务端进程是否死亡的生死情况

public class Binder implements IBinder {
    public void linkToDeath(DeathRecipient recipient, int flags) {
    }


    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
        return true;
    }
}

final class BinderProxy implements IBinder {
    // 向Binder驱动注册死亡回调
    public native void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException;
    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
}
RemoteCallbackList

在某些场景下,Binder服务端需要回调每一个Binder代理对象对应的回调接口,要先确保Binder代理对象没有死亡,才发送RemoteCallbackList内部是通过DeathRecipient和匿名Binder来实现的。以A,B接口来举例,客服端先获取A接口的Binder代理对象, 每一个客服端都创建一个实现了B接口的Binder服务对象,通过A接口,把实现了B接口的Binder服务对象传给A,通过kernel层的转换,A服务中最终获取到的是B接口的代理对象

在这里插入图片描述,简要关系图如下:
在这里插入图片描述

public interface IInterface
{
    public IBinder asBinder();
}

public class RemoteCallbackList<E extends IInterface> {
    public boolean register(E callback, Object cookie) {
        synchronized (mCallbacks) {
            if (mKilled) {
                return false;
            }
            // Flag unusual case that could be caused by a leak. b/36778087
            logExcessiveCallbacks();
            IBinder binder = callback.asBinder();
            try {
                Callback cb = new Callback(callback, cookie);// 最终也是通过linkToDeath实现
                binder.linkToDeath(cb, 0);
                mCallbacks.put(binder, cb);
                return true;
            } catch (RemoteException e) {
                return false;
            }
        }
    }
}

// example IInterface接口为android.os.IInterface,需要Binder通信的接口类才符合IInterface接口
public interface IMyAidlInterface extends android.os.IInterfacepublic static abstract class Stub extends android.os.Binder 
    implements com.hhtc.deathrecipient.IMyAidlInterface {
    }
    private static class Proxy implements com.hhtc.deathrecipient.IMyAidlInterface {
    }
}

git Demo代码

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RemoteCallbackListAndroid框架中的一个类,用于管理回调接口对象。它提供了注册、注销和通知回调接口对象的功能。当客户端需要与服务端进行通信并接收回调时,可以使用RemoteCallbackList来管理回调接口对象。 以下是RemoteCallbackList的一些特点和用法: 1. RemoteCallbackList是线程安全的,可以在多线程环境下使用。 2. 当客户端调用registerCallback方法时,会将回调接口对象添加到RemoteCallbackList中。 3. 当客户端调用unregisterCallback方法时,会将回调接口对象从RemoteCallbackList中移除。 4. 当服务端需要通知客户端时,可以调用notifyCallbacks方法,遍历RemoteCallbackList中所有的回调接口对象,并调用其相应的方法,实现回调的功能。 以下是一个使用RemoteCallbackList的示例代码: ```java // 创建一个RemoteCallbackList对象 RemoteCallbackList<MyCallback> callbackList = new RemoteCallbackList<>(); // 客户端注册回调接口对象 MyCallback callback = new MyCallback(); callbackList.register(callback); // 服务端通知客户端 int count = callbackList.beginBroadcast(); for (int i = 0; i < count; i++) { MyCallback callback = callbackList.getBroadcastItem(i); callback.onCallback(); } callbackList.finishBroadcast(); // 客户端注销回调接口对象 callbackList.unregister(callback); ``` 请注意,上述示例中的MyCallback是一个自定义的回调接口,你需要根据实际需求来定义和实现该接口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值