搭建IPC通信框架(RPC)

本文介绍了在Android中构建一个简单的RPC框架,用于进程间通信。通过自定义注解和服务注册,实现了跨进程调用,封装了Binder通信,简化了AIDL的使用。文章还提供了Demo展示了如何在服务进程中开启定位服务,并在主进程获取结果。
摘要由CSDN通过智能技术生成

Android进程通讯方式有很多,如Socket、ContentProvider、共享文件(这种方式的缺点是不支持并发写,同时需要手动操作IO)、AIDL、Messenger(底层实现也是AIDL)等。关于AIDL和Messenger的使用详见Android知识点总结(四)进程间通信
Android中IPC方式的使用不是有诸多限制,就是使用起来比较麻烦,所以搭建一套简单易用的IPC框架是很有必要的。
RPC:从客户端上通过参数传递的方式调用一个远程函数并得到返回的结果,隐藏底层的通讯细节。在使用形式上就像调用本地函数一样去直接调用远程函数

场景

在服务进程中开启定位服务(demo里对应GpsService),在App主进程或者其他APP中获得定位结果(demo对应MainAcivity)。

框架使用预览

在这里插入图片描述

1. 编写业务接口及接口实现
ILocationManager

    @ServiceId("LocationManager")
    public interface ILocationManager {
        Location getLocation();
    }

LocationManager

   @ServiceId("LocationManager")
    public class LocationManager {
        private static final LocationManager OUR_INSTANCE = new LocationManager();
    
        public static LocationManager getDefault() {
            return OUR_INSTANCE;
        }
    
        private LocationManager(){}
    
        private Location location;
    
        public Location getLocation() {
            return location;
        }
    
        public void setLocation(Location location) {
            this.location = location;
        }
    }

二者通过自定义注解的方式相关联,RPC框架主要就是通过反射业务接口的实现类LocationManager来完成通信。

2. 服务进程使用方法
将业务接口实现类注册到RPC框架即可,RPC框架内部通过反射的方式拿到LocationManager的相关信息,通过AILD将数据传递到主进程。

/**
 * 服务进程
 */
public class GpsService extends Service {
    public GpsService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //模拟定位
        LocationManager.getDefault().setLocation(new Location("岳麓区天之道", 1.1d, 2.2d));

        //将LocationManager注册到框架
        IPC.regist(LocationManager.class);
    }
}

3. 主进程使用方法

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
		//开启服务进程
        startService(new Intent(this, GpsService.class));
		//通过RPC框架连接服务 IPCService服务是框架内部的公共服务,IPCService0是内部服务的子类
		//和服务进程设置为同一进程
        IPC.connect(this, IPCService.IPCService0.class);

    }
    public void showLocation(View view) {
        //主进程利用框架获取业务实现类的代理对象,然后用代理对象直接调用接口方法
        //使用形式上就像调用本地函数一样去直接调用远程函数
       ILocationManager location = IPC.getInstanceWithName(IPCService.IPCService0.class, ILocationManager.class, "getDefault");
       Toast.makeText(this, "当前位置:" + location.getLocation(), Toast.LENGTH_LONG).show();
    }
}

以上就是整个框架的应用示例

RPC框架实现原理

接下来就从零开始手写整个RPC框架

在这里插入图片描述
1、业务注册

public class IPC {
    //服务端
    //==================================================================
    //注册
    public static void regist(Class<?> service) {
        Registry.getInstance().regist(service);
    }
    ...
}

IPC.java只是对外的一个窗口,真正的注册实现在Registry


public class Registry {
    private static volatile Registry instance;
    /**
     * 服务表 记录业务接口实现类的Class对象 对应本例即LocationManager
     */
    private ConcurrentHashMap<String, Class<?>> mServices = new ConcurrentHashMap<>();
    /**
     * 方法表 记录业务接口实现类的相关方法
     */
    private ConcurrentHashMap<Class<?>, Map<String, Method>> mMethods = new ConcurrentHashMap<>();
    /**
     * 业务实现类的实例,要反射执行非静态方法,是需要一个实例对象的,所以把实例保存起来
     */
    private Map<String, Object> mObjects = new HashMap<>();

    private Re
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值