美文网首页安卓开发程序员
AS下的进程间通信的实现

AS下的进程间通信的实现

作者: dev晴天 | 来源:发表于2017-12-08 14:11 被阅读10次

前言:今天学习了进程间的通信,感觉实现比较繁琐的,于是在这记录一篇如何实现进程间的通信。

补充:
本地服务:运行在自己应用里的服务。
远程服务:运行在其他应用里的服务(可以实现进程间通信 ipc(Inter-Process
Communication))

andoid IPC方式主要有以下几种:
1.bundle :
简单易用 但是只能传输Bundle支持的对象 常用于四大组件间进程间通信
2.文件共享:
简单易用 但不适合在高并发的情况下 并且读取文件需要时间 不能即时通信 常用于并发程度不高 并且实时性要求不高的情况
3.AIDL :
功能强大 支持一对多并发通信 支持即时通信 但是使用起来比其他的复杂
需要处理好多线程的同步问题 常用于一对多通信 且有RPC 需求的场合(服务端和客户端通信)
4.Messenger :
功能一般 支持一对多串行通信 支持实时通信 但是不能很好处理高并发情况只能传输Bundle支持的类型 常用于低并发的无RPC需求一对多的场合
5.ContentProvider :
在数据源访问方面功能强大 支持一对多并发操作 可扩展call方法 可以理解为约束版的AIDL 提供CRUD操作和自定义函数 常用于一对多的数据共享场合
6.Socket :
功能强大 可以通过网络传输字节流 支持一对多并发操作 但是实现起来比较麻烦 不支持直接的RPC 常用于网络数据交换

总结起来
当仅仅是跨进程的四大组件间的传递数据时 使用Bundle就可以 简单方便
当要共享一个应用程序的内部数据的时候 使用ContentProvider实现比较方便 当并发程度不高 也就是偶尔访问一次那种 进程间通信 Messenger就可以 当设计网络数据的共享时 使用socket 当需求比较复杂 高并发 并且还要求实时通信 而且有RPC需求时 就得使用AIDL了
文件共享的方法用于一些缓存共享 之类的功能

现在有个需求:在第一个应用的服务中有个方法,要求你在带二个应用中点击按钮调用第一个服务的方法。
通过上面的需求我们来做个简单的demo来实现进程间的通信。

一 首先建立两个安卓工程:
(AIDLDemo1 的app name取名字 为远程服务)


image.png

(AIDLDemo2 的app name取名字 为本地服务)

image.png

二 本地服务中
1 建立一个服务取名RemoteService(清单文件别忘了注册下服务)
在本地服务中定义一个方法(远程服务中要操作的方法)通过接口(自定义个)暴露出去。


image.png

2 定义类MyBind 继承Binder 实现你定义的接口(由于写到后面需要修改此处。 此处逻辑为基本逻辑不再粘贴)

3 返回接口实现子类的对象


image.png

二 远程服务中进行绑定服务

1 声明Intent对象

        Intent intent = new Intent();
// 此处 (this,远程服务的类名.class)是行不通的(因为远程服务的类名.class 本应用中没有的) 通过下面的可以       intent.setAction("com.example.administrator.aidldemo1.RemoteService");

注 此action为远程服务中服务注册时配的Intent-fliter中配的自定义action

2 绑定服务

bindService(intent, conn,BIND_AUTO_CREATE);

private class MyServiceConnection implements ServiceConnection{

       @Override
       public void onServiceConnected(ComponentName name, IBinder service) {
             
    
              * 3 拿中间人对象
              * */
           iinterface = Iinterface.Stub.asInterface(service);
       }

       @Override
       public void onServiceDisconnected(ComponentName name) {

       }
   }

    @Override
    protected void onDestroy() {
        // 解绑的逻辑(不解绑会报错)
        unbindService(conn);
        super.onDestroy();
    }

3 onServiceConnected 中:
/*链接成功获得中间人对象 但是此时不是同一个应用Iservice对象在此处使用不了
* aidl技术孕育而生 解决此困难(一种语言专门解决进程间的通信)

实现步骤:
1 到远程进程的App中 找到你定义的接口 进行鼠标右键show in explorer
把接口的.java文件 改为.aidl (带public 都去掉 本语言本身就是 公开通信本来就是public)

image.png

2 此时你的自定义MyBind类会报错
* 此时系统会自动生成一个文件Iservice.java 内部有Stub类 继承了
Bined 实现了Iservice
* 你只需要吧报错的自定义类直接继承Stub即可(注: 此处studio不会自动升成R文件还需这样处理后再继承Stub:

在你的module的main下面新建一个aidl文件夹,如图


image.png

在这个aidl文件夹下面新建一个包,包名必须和你的AndroidManifest.xml中package的包名相同。然后把你的aidl文件放入到这个包下。
(此处我把原来的aidl文件复制走一份到此包下)

image.png

然后rebuild一下就可以在build/source/aidl/debug/下生成了相对应的.java文件了


image.png image.png

此时 MyBind 可以继承Stub类了
(As中必须这样处理否则你是用不了这个类的 不会自动生成 eclipse会子动生成.java文件)


image.png

3
保证两个应用有同一个aidl文件(在本地服务中建立一个与远程服务相同包的文件夹 把aidl文件和.java(Iinterface)拷贝过来)

image.png

4 此时就可以使用中间人对象了


image.png

5 按钮中调用方法


image.png

6 特别注意 在远程服务中注册服务时要配置 自定义个action

image.png

运行结果:

image.png image.png image.png

经过一番的折腾终于成功了,虽然输出的结果很简单,但是现在你已经初步学会了如何搭载进行进程间的通信。

在完成中也遇到了一点麻烦 参考链接:http://blog.csdn.net/suncold123/article/details/48785709感谢这位大大的文章。

相关文章

  • AS下的进程间通信的实现

    前言:今天学习了进程间的通信,感觉实现比较繁琐的,于是在这记录一篇如何实现进程间的通信。 补充:本地服务:运行在自...

  • 【python】进程间通信:Queue的详细用法

    关于python 进程间通信 Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信。 进程间通...

  • 操作系统基础(进程间通信)

    一.进程间通信的实现 进程间通信 (Inter-process communication, IPC):运行在不同...

  • Binder机制总结

    一、Binder机制概述 在Android开发中,很多时候我们需要用到进程间通信,所谓进程间通信,实现进程间通信的...

  • 8.进程间通信与进程池

    进程间通信与进程池 进程间通信-Queue 通常利用multiprocessing模块的Queue实现多线程之间的...

  • Android 底层的进程间同步机制

    作者:Android面试官 进程间通信的经典实现 进程间通信(Inter-process communicatio...

  • Windows下实现进程间通信

    为了完成本周操作系统的作业,同时也学习一下这块的相关知识,所以写个博客记录下。 进程与线程 进程是操作系统中最核心...

  • Python Socket 网络编程

    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络...

  • 1.5.3 Python进程使用 -- Queue

    进程间通信-Queue Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信。 1. Queu...

  • iOS进程间通信

    线程间通信 :通过performSelector系列的方法 可以实现 各种线程间的通信(通信 :调用与传参)进程间...

网友评论

    本文标题:AS下的进程间通信的实现

    本文链接:https://www.haomeiwen.com/subject/skdeixtx.html