IPC机制:

目录

Linux和Android的IPC机制:

1.Linux中的IPC机制:

1.1:管道:

1.2:信号:

1.3:信号量:

1.4:消息队列:

1.5:共享内存:

1.6:套接字:

2.Android中的IPC机制:

2.1:序列化:

2.2:Messenger:

2.3:AIDL:

2.4:Bundle:

2.5:文件共享:

2.6:ContentProvider:

开启多进程:


Linux和Android的IPC机制:

IPC全称为Inter-Process Communication,含义为进程之间的通信,也就是两个进程之间进行数据交换的过程。在Android和Linux中都有自己的IPC机制。

1.Linux中的IPC机制:

Linux 中提供了很多进程间通信机制,主要有管道(Pipe)、信号(Sinal)、信号量(Semophore)、消息队列(Message)、共享内存(Share Memory)和套接字(Socket)等。

1.1:管道:

管道是Linux由UNIX继承过来的进程间的通信机制,它是UNIX早期的一个重要通信机制。管道的主要思想是在内存中创建一个共享文件,从而使通信双方利用这个共享文件来传递信息。这个共享文件比较特殊,它不属于文件系统并且只存在于内存中。另外,管道采用半双工通信方式,数据只能在一个方向上流动。

1.2:信号:

信号是软件层次上对中断机制的一种模拟,信号是一种异步通信方式,进程不必通过任何操作来等待信号的到达。信号可以在用户空间进程和内核之间直接交互,内核可以利用信号来通知用户空间的进程发生了哪些系统事件。信号不适用于信息交换,比较适用于进程中断控制。

1.3:信号量:

信号量是一个计数器,用来控制多个进程对共享资源的访问。信号量常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。信号量主要作为进程间及同一进程内不同线程之间的同步手段。

1.4:消息队列:

消息队列是消息的链表,具有特定的格式,消息队列存放在内存中由消息队列标识符进行标识,并且允许一个或多个进程向它写入与读取消息。使用消息队列会使信息复制两次,因此对于频繁通信或者信息量大的通信不宜使用消息队列。

1.5:共享内存:

共享内存的多个进程可以直接读写一块内存空间,是针对其他通信机制运行效率较低而设计的。为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。这样,进程就可以直接读写这一块内存而不需要进行数据的复制,从而大幅度提高效率。

1.6:套接字:

套接字是更基础的进程间通信机制,与其他通信机制不同的是,套接字可用于不同机器之间的进程间通信。

2.Android中的IPC机制:

Android系统是基于Linux内核的,在Linux内核基础上又拓展出了一些IPC机制。Android 系统除了支持套接字,还支持序列化、Messenger、AIDL、Bundle、文件共享、ContentProvider和Binder等。

2.1:序列化:

序列化指的是Serializable/Parcelable接口,Serializable接口是Java提供的一个序列化接口,是一个空接口,为对象提供标准的序列化和反序列化操作。Parcelable接口是Android中的序列化方式,更适合在Android平台上使用。虽然Parcelable接口用起来比较麻烦,但是其效率很高。

2.2:Messenger:

Messenger在Android应用开发中的使用频率不高,可以在不同进程中传递Message对象,在Message中加入我们想要传递的数据就可以在进程间进行数据传递了。Messenger是一种轻量级的IPC方案,并对AIDL进行了封装。

2.3:AIDL:

AIDL全称为 Android Interface Definition Language,即Android 接口定义语言。Messenger是以串行的方式来处理客户端发来的信息的,如果有大量的消息发送到服务端,那么服务端仍然逐个处理再响应客户端显然是不合适的。虽然Messenger可以用于进程间数据传递,但是却不能满足跨进程的方法调用,这个时候就需要使用AIDL了。

2.4:Bundle:

Bundle实现了Parcelable接口,所以它可以在不同的进程间传输。Activity、Service、Receiver都是在Intent中通过Bundle来进行数据传递的。

2.5:文件共享:

两个进程通过读写同一个文件来进行数据共享,共享的文件可以是文本、XML,JSON。文件共享适用于对数据同步要求不高的进程间通信。

2.6:ContentProvider:

ContentProvider为存储和获取数据提供统一的接口,它可以在不同的应用程序之间共享数据,ContentProvider本身就是适合进程间通信的。ContentProvider底层实现也是 Bindr,但是使用起来比AIDL要容易许多。系统中很多操作都采用了ComtentProvider,例如通讯录、音视频等,这些操作本身就是跨进程进行通信的。

开启多进程:

既然要讲解Android应用开发中的IPC机制,那么就需要代码的示例,而这些示例都需要开启多进程。Android应用要开启多进程的原因,主要有以下几点:

  1. 单进程所分配的内存不够,需要更多的内存。早期的Android系统只为一个单进程的应用分配了16MB的可用内存,随着手机硬件的提升和Android系统的改进,虽然可分配内存越来越多,但仍旧可以通过开启多进程来获取更多内存来处理自己App的业务。
  2. 独立运行的组件,比如个推,它的服务会另开启一个进程。
  3. 运行一些“不可见人”的操作,比如获取用户的隐私数据,比如防止双守护进程被用户杀掉。
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent myServiceIntent=new Intent(MainActivity.this,MyService.class);
        this.startService(myServiceIntent);
    }
}
public class MyService extends Service {
    private static final String TAG="ssss";
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public int onStartCommand(Intent intent,int flags,int startId){
        Log.i(TAG,"MainActivity is created");
        return START_STICKY;
    }
    @Override
    public void onDestroy(){
        Log.i(TAG, "onDestroy ");
    }
    @Override
    public void onCreate(){
        Log.i(TAG, "onCreate");
    }
}
 <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        tools:targetApi="31">
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"
            android:process=":remote"></service>


        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

其中重要的是android:process属性,表示是否要开启一个新的进程运行,而后面的命名方式有两种,分别是:加冒号和不加冒号,其中加冒号的进程名,表示这个新的进程对这个应用来说是私有的,其他的应用组件不能和新的进程运行在同一个进程中。而不加冒号的,表示这个服务运行在以这个名字命名的全局的进程中,当然前提的有权限,将允许不同应用的组件运行在同一个进程中,从而减少资源的占用。注意:这种写法会导致Application会运行两次,两个进程都执行了oncreate方法。解决的办法是得到每个进程的名字,根据不同的进程进行不同的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mo@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值