1、前言 IPC

PC(Inter-Process Communication)进程间通信,提供了各种进程间通信的方法。不仅是Android,其他语言也大很多情况下需要进程间通信的。Android本质上属于Linux,它的跨进程通信也基于Linux进程通信的原理。在Linux C编程中有几种方法
(1) 半双工Unix管道
(2) FIFOs(命名管道)
(3) 消息队列
(4) 信号量
(5) 共享内存
(6) 网络Socket

以上方法都可以实现进程间的通讯,但Android并没有使用以上6种现成的通信方法,而是自己开发Binder驱动,至于为什么重新开发Binder,可参考知乎上的回答:
https://www.zhihu.com/question/39440766?sort=created

大致原因:安全,性能,稳定。
本篇大致围绕下面几个问题,大致做出回答

  1. 什么是IPC,大致适应场景
  2. Binder机制
  3. Binder与AIDL
  4. 如何使用AIDL

1、为什么会有IPC?

因为在很多情况下,我们需要共享进程或者进程间通信,场景
1、下载的音乐文件在文件管理器中,当前我正在播放因为,我在文件管理器删除音乐(文件不存在了),当前音乐播放器是不是该停止呢?
2、第三方APP集成支付宝付款时,第三方应用怎么样调起支付宝用于支付呢
其实使用的场景很多,要实现上面的功能就得使用IPC。
Android IPC、Binder和AIDL_第1张图片

内存共享

在用户空间中没有办法共享,因此进程间不能通信,但在内核空间中可以共享,不同的APP要进行通信,可以通过使用内核空间来做到,这样就产生IPC机制,IPC是用于解决这些问题的。为了做到IPC,Android 中提供了Binder机制,来解决进程通信问题

2、Binder机制

Android IPC、Binder和AIDL_第2张图片
服务端:Binder服务端其实就是一个Binder对象,对象建立后,启动一个线程,这个线程接收Binder驱动发送的消息,并执行onTransact()方法,执行服务代码。
Binder驱动:当服务端对象创建时,同时会在Binder驱动中创建一个mRemote对象,该对象类型也是Binder类,客户端要过程访问时,都是通过mRemote对象。
客户端:客户端想要访问远程服务时,必须获取远程服务在B inder中对应的mRemote 对象,获取方法就是通过AIDL

3、Binder与AIDL

AIDL(Android Interface Define Language),是android的一种接口定义语言。借助它,你可以定义接口,使得客户端和服务端之间实现进程间通信。
Binder是Android的一个类,它实现了IBinder接口。从IPC角度来说,Binder是android中的一种跨进程通信方式。通过这个Binder对象,客户端就可以获取服务端提供的服务或数据,这里的服务包括普通服务和基于AIDL的服务。

也就是说Binder是用来实现远程服务访问的,AIDL则主要负责远程访问的主要内容,这些内容则用AIDL中的接口来描述。

4、AIDL使用示例

示例做一个进程间通信的Demo,在AIDLServer中新建一个方法,返回一个字符串,在另一个Client的APP中调用。
Android IPC、Binder和AIDL_第3张图片

1、服务端代码

1.创建一个AIDL文件:

// IMyAidlInterface.aidlpackage com.example.aidlservice;// Declare any non-default types here with import statementsinterface IMyAidlInterface {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,            double aDouble, String aString);    String getString();}

2、新建服务,这个服务就是远程访问的服务,用于客户端调用

package com.example.aidlservice;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;/** * Created by yuxiaogang on 2017/8/5. */public class RemoteService extends Service {    @Nullable    @Override    public IBinder onBind(Intent intent) {        return iMyAidlInterface;    }    private IMyAidlInterface.Stub iMyAidlInterface = new IMyAidlInterface.Stub() {        @Override        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {        }        @Override        public String getString() throws RemoteException {            return "im from server";        }    };}

3、启动服务:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private Button btn_bind;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn_bind = (Button) findViewById(R.id.btn_bind);        btn_bind.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn_bind:                Intent intent = new Intent(this, RemoteService.class);                bindService(intent, new ServiceConnection() {                    @Override                    public void onServiceConnected(ComponentName name, IBinder service) {                        Toast.makeText(MainActivity.this, "success", Toast.LENGTH_SHORT).show();                    }                    @Override                    public void onServiceDisconnected(ComponentName name) {                        Toast.makeText(MainActivity.this, "failed", Toast.LENGTH_SHORT).show();                    }                }, BIND_AUTO_CREATE);                break;        }    }}

2、客户端

客户端就是实际上需要调用远程服务,首先引进AIDL文件,注意AIDL文件的位置和包名。可以直接从Service中复制过来。编译后,客户端就可以调用到服务端的方法了

public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private Button btn_msg;    private TextView text;    private IMyAidlInterface iMyAidlInterface;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn_msg = (Button) findViewById(R.id.btn_msg);        text = (TextView) findViewById(R.id.text);        btn_msg.setOnClickListener(this);    }    @Override    protected void onResume() {        super.onResume();        Intent intent = new Intent();        intent.setAction("com.example.aidlservice.RemoteService");       // intent.setPackage("com.example.aidlservice");        bindService(intent, new ServiceConnection() {            @Override            public void onServiceConnected(ComponentName name, IBinder service) {                iMyAidlInterface=IMyAidlInterface.Stub.asInterface(service);                Log.i("MainActivity", "onServiceConnected");            }            @Override            public void onServiceDisconnected(ComponentName name) {                Log.i("MainActivity", "onServiceDisconnected");            }        }, BIND_AUTO_CREATE);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn_msg:                try {                    text.setText(iMyAidlInterface.getString());                } catch (RemoteException e) {                    e.printStackTrace();                }                break;        }    }}

更多相关文章

  1. Android的进程与线程模型
  2. Android客户端和服务器端数据交互的第一种方法
  3. android 杀死进程的三种方法
  4. Android Studio 配置使用 AIDL 跨应用通信示例
  5. android 进程

随机推荐

  1. Android(安卓)Studio 新手常见问题汇总
  2. android 窃听电话
  3. Android_开发 Android中CookieManager的
  4. android json httppost方式联网
  5. android弹出下拉选择菜单,单选,多选
  6. android 中让activity全屏幕显示
  7. 安卓第三次作业
  8. xbmc 从android_main启动时的部分步骤记
  9. RelativeLayout
  10. Android富文本图文混排、粗体、斜体、图