用时多日终于肝爆“IPC”

作者: 程序老秃子 | 来源:发表于2022-04-28 16:01 被阅读0次

Android IPC简介

IPC 全称为Inter-Process Communication,译为“跨进程通信”含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程;在这里要着重提一下,进程(Process)和线程(Thread)是完全不一样的概念,两者不能混淆;在操作系统的概念里,进程是CPU的调度单元,而线程是CPU的最小调度单位,一个进程包含一个或一组线程,两者为包含关系

Android 进程间 IPC 通信方式

Android进程间通信(IPC:Inter-Process Communication)的几种主要方式如下:

使用Bundle ----> 用于android四大组件间的进程间通信

android的四大组件都可使用Bundle传递数据 所以如果要实现四大组件间的进程间通信 完全可以使用Bundle来实现 简单方便

使用文件共享 ---->用于单线程读写

这种方式在单线程读写的时候比较好用 如果有多个线程并发读写的话需要限制线程的同步读写
另外 SharePreference是个特例 它底层基于xml实现 但是系统对它的读写会基于缓存,也就是说再多进程模式下就变得不那么可靠了,有很大几率丢失数据

使用Messenger ---->用于可存放在message中的数据的传递

使用这个方式可以在不同进程间传递message对象 这是一种轻量级的IPC方案 当传递的对象可以放入message中时 可以考虑用这种方式

但是msg.object最好不要放;因为不一定可以序列化

Android IPC 调用

Android是基于linux内核的;所以linux支持的 IPC ,Android 都用到了;比如命名管道,共享内存;除此外,Android 还使用了一套自己独特的 IPC 方式 Binder .;主要用于2个进程间的远程调用,但是这里就牵扯远程调用如何传递参数,如何回传结果;这需要调用者对数据进行打包和解包,是一个繁琐的过程

为此,Android 引入了 AIDL (Android interface description launguage). 开发人员定义好 AIDL ,Android 会根据 AIDL 的描述生产 stub 代码,帮助调用者对数据打包,解包;开发人员所要做的事是继承stub代码,实现stub代码中的函数;这些函数是你在aidl中定义的

AIDL的实现

在Android中有多种实现IPC的方式,各有各的优缺点,我们拿其中一种最常用方式来更深入的了解一下Android中IPC的实现方式,从而彻底理解其工作方式

我们用一个最简单的场景:服务端提供计算的方法计算两个数之和并返回;客户端调用服务端的方法得出结果并显示

首先是服务端:

我们首先创建一个AIDL文件,其实就是定义我们的方法接口

// IMyAdd.aidlpackage 
test.jiao.com.aidl;
interface IMyAdd {
    int add(int first,int second);
}

其中定义了一个两个数相加的方法接下来我们创建一个Service

package test.jiao.com.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;

/**
 * date :2016/12/26
 * author :SuperJiao
 * Description
 */
public class MyAddService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }


    private Binder mBinder = new IMyAdd.Stub() {
        @Override
        public int add(int first, int second) throws RemoteException {
            return first + second;
        }
    };
}

我们在Service中实现了我们定义的AIDL接口,并且服务端在绑定接口的时候将服务端的IBinder对象返回给客户端;客户端拿到服务端的IBinder对象就可以调用服务端的方法了

客户端实现如下:

和服务端定义一个一模一样的aidl文件(包名、方法名,参数必须一致)

// IMyAdd.aidlpackage 
test.jiao.com.aidl;
interface IMyAdd {
    int add(int first,int second);
}

绑定服务端的服务

package test.jiao.com;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.Toast;

import test.jiao.com.aidl.IMyAdd;

public class MainActivity extends Activity {
    private Button bt_aidl_add;
    private IMyAdd mIMyAdd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        start();
    }


    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Toast.makeText(MainActivity.this, "绑定服务成功", Toast.LENGTH_SHORT).show();
            mIMyAdd = IMyAdd.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    private void start() {
        bindService();//绑定服务
        bt_aidl_add = (Button) findViewById(R.id.bt_aidl_add);
        bt_aidl_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mIMyAdd != null) {
                    try {
                        int result = mIMyAdd.add(5, 5);
                        Toast.makeText(MainActivity.this, result + "", Toast.LENGTH_SHORT).show();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(MainActivity.this, "计算失败", Toast.LENGTH_SHORT).show();
                }
            }
        });

    }


    //绑定服务
    private void bindService() {
        Intent intent = new Intent();
        intent.setAction("com.jiao.myaidl.action.MYADD_SERVICE");
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        unbindService(serviceConnection);//解绑服务
        super.onDestroy();
    }

}

接下来我们来分析一下整个AIDL的执行过程:

● 首先服务端的MyAddService在自己的进程中向Binder驱动申请创建了一个MyAddService的Binder实体;Binder驱动为MyAddService创建了位于内核中的Binder实体节点以及Binder的引用,并将名字和新建的引用打包传递给SM(实体没有传给SM),通知SM注册一个MyAddService

● SM收到数据包后,从中取出MyAddService名字和引用,填入一张查找表中。在启动服务的时候,SM就会从这张查找表中查找相应的服务

● 客户端Client申请访问MyAddService,SM就会从请求数据包中获得MyAddService的名字,在查找表中找到该名字对应的条目,取出Binder的引用打包回复给client;之 后,Client就可以利用MyAddService的引用使用MyAddService的服务了

如果需要文章中使用的源码的同学,可以顺手给我点赞评论支持一下

资料获取方式

现在点击:免费获取更多Android进阶资料,学习笔记,面试真题

Android架构师之路还很漫长,与君共勉

PS:有问题欢迎指正,欢迎大家点赞评论,可以在评论区留下你的建议和感受

相关文章

  • 用时多日终于肝爆“IPC”

    Android IPC简介 IPC 全称为Inter-Process Communication,译为“跨进程通信...

  • 2020-02-26

    在连续两天爆肝之后,我终于让自己能够放心歇息一会儿,因为突然想到通了自己做抖音的定位和模式。 爆肝是因为,在准备了...

  • 来,干了这篇文案,我还能再熬一晚……

    爆肝 爆肝:一个在游戏玩家,加班族等人群中使用的用语,常以简称“肝”作为动词使用。 爆肝用于指需要耗费大量的时间和...

  • 爆肝

    最近下巴长了好几个痘。突然想到前一段时间因为某件令人恶心的事情去找某要职领导盖章的事,我边诉说来意边不由自主的抠痘...

  • 爆肝

    1.将近凌晨两点才睡,心口隐隐发疼,很久很久都没熬到这么晚过,果然伤身体啊。总归是补完了前一天的语料库错词,七点半...

  • 爆肝

    1.将近凌晨两点才睡,心口隐隐发疼,很久很久都没熬到这么晚过,果然伤身体啊。总归是补完了前一天的语料库错词,七点半...

  • 所有欠下的债,都得还

    一个预估错误+拖延,导致 现在还在爆肝冲击最后的deadline爆肝 去找外援 去淘宝买东西 交货质量参差不齐 耽...

  • 时隔多日终于回来了

    下了班,换去工服就直接出公司了。 一路畅通无阻,出了公司,在街上人流熙熙攘攘,只是不那么多而已,可能是早上大家都赶...

  • 探秘"中国第一鬼村"封门村,河南的一个小村为何闻名全国?

    文/爆肝;首发于《爆肝的灵异笔记》,侵权必究。 眼见不一定为实,耳听也可能非虚! 蒙娜丽莎真的在微笑吗? 美国真的...

  • 纵欲熬夜,惹恼了肝,人就废了

    纵欲熬夜,惹恼了肝,人就废了 肝好命就好。 肝不好,脾胃也好不到哪,茶饭不思,气饱了,头晕目眩……熬夜爆肝的危害远...

网友评论

    本文标题:用时多日终于肝爆“IPC”

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