如何使用VPNService
vpnService内部构成
VpnService继承service,内部维护了一个VPNManagerService的代理对象VPNManager,同时对外提供Builder方法用于构造VpnConfig。
我们使用VpnConfig设置好我们需要的VPNService的配置参数,由VPNManager通过AIDL传递给VPNManagerService,在对应的VPN对象里建立vpn连接。
establish 方法原理
establish 方法属于核心方法,我们建立连接主要靠这个方法。
- 主要流程
- 通过AIDL将vpnconfig对象传递给VPNManagerService
- service中查找到当前的VPN对象
- 生成虚拟网卡tun
- 在VPN对象中对比老的链路,决定是否复用
- 如果不复用,则创建新的LinkProperties对象,同时创建其对应的 NetworkCapabilities 和 NetworkAgent对象
- 通过NetworkAgent来和底层物理链路建立连接
- 回收旧tun,返回新tun
图中可以看到,这里会检查是否调用prepare方法,那么这个方法主要做什么事情呢?
prepare 方法原理
VPNService的prepare方法是我们想要使用vpn时候,调用的第一个方法,通过这个方法来获取一个intent,这个intent可以通过startActivityForResult来给用户弹一个系统VPN权限确认弹窗,用户只有同意了该权限,那么才可以继续使用vpn,否则将无法使用该功能。
- 对于prepare的核心操作是在vpn对象中,会依次判断
- 对于当前包名,是否之前已经授权过,对于同一个包名只需要授权一次。
- 如果当前存在正在连接的VPn,会将vpn断开,重置网络vpn状态
- 告知被断开VPn的service,调用其onRevoke方法
对于获取到的Intent,通过在Activity中调用startActivityForResult方法来显示弹窗,用户点击弹窗后,如果当前VPNManagerService中没有该用户对应的Vpn对象,那么会创建一个保存到SpareArray中。