AIDL实现不同应用间的通信

  最近做项目遇到一个问题,要通过我们的主应用给第三方应用发消息。至此接触到了AIDL。经过一番研究,终于懂了该怎么用了。在这里记录下来,一边后续继续了解

其中许多知识点都是参考http://www.poemcode.net/2010/05/aidl-ipc/

  AIDL——android接口定义语言。它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。

  要使用AIDL实现不同应用之间的通信,则主要部分就是实现.aidl文件。

1、实现.aidl文件 IMessage

package com.wyy.aidl;

interface IMessage{
    String getMessage();
}

aidl文件里就是主要是写接口,就是要进行通信的方法。

  aidl文件里的代码跟java代码很类似,但也有许多不同之处。aidl文件里定义的接口不要有修饰符(如public  private等)。

AIDL 支持的数据类型划分为四类,第一类是 Java 编程语言中的基本类型,第二类包括 String、List、Map 和 CharSequence,第三类是其他 AIDL 生成的 interface,第四类是实现了 Parcelable protocol 的自定义类。

其中,除了第一类外,其他三类在使用时均需要特别小心。

使用第二类时,首先需要明白这些类不需要 import,是内嵌的。其次注意在使用 List 和 Map 此二者容器类时,需注意其元素必须得是 AIDL 支持的数据类型,List 可支持泛型,但是 Map 不支持,同时另外一端负责接收的具体的类里则必须是 ArrayList  HashMap

使用第三、四类时,需要留意它们都是需要 import 的,但是前者传递时,传递的是 reference,而后者则是 value。

在创建 .aidl 文件的过程中,应该注意一旦 method 有参数,则需注意在前面加上 in, out 或 inout,它们被称为 directional tag,但是对于基本类型的参数,默认就是 in,并且不会是其他值。

2、实现interface

  AIDL 为你生成一个 interface 文件,文件名称和 .aidl 文件相同。如果使用 Eclipse 插件,则 AIDL 会在构建过程中自动运行,如果不使用插件,则需要先使用 AIDL。

生成的 interface 会包含一个抽象内部类 Stub,它声明了在 .aidl 文件里的所有方法。Stub 也定义了一些帮助方法,比较常用的有 asInterface(),其接收一个 IBinder 作为参数,并且返回一个 interface 的实例用来调用IPC方法。
  
要实现aidl里定义的接口,就需要了解service,新建一个项目作为service端,在service里实现Imessage.stub

public class MyService extends Service {

    private IBinder mIbinder = new MyBinder();
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return mIbinder;
    }
    
    
    public String getS(){
       return  "从服务端获得的消息内容";
    }

    private class MyBinder extends IMessage.Stub{

        @Override
        public String getMessage() throws RemoteException {
            // TODO Auto-generated method stub
            return getS();
        }
        
    }
}

这个环节是重中之重,需要特别小心的有两点,其一是抛出的所有异常均不会发给调用者;其二是IPC调用是同步的,这意味IPC服务一旦花费较长时间完成的话,就会引起ANR,应该将这样的操作放在单独的线程里。

3、向客户端公开 Interface

  

public class MainActivity extends Activity {
    private TextView tv1;
    private MyConnection con = new MyConnection();
    MyBroadCastReceive myReceiver = new MyBroadCastReceive();
    private IMessage message;
    Intent it;
    DemoBService service1 = new DemoBService();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.activity_main);
        tv1 = (TextView) findViewById(R.id.tv1);
        
        Intent service = new Intent("com.wyy.aidl.myservice");
        if(bindService(service, con, BIND_AUTO_CREATE)){
            Log.i("Mainactivity", "绑定成功");
        }      
        
    }
    private class MyConnection implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            Log.i("MyConnection--onServiceConnected()", "message != null");
            message = IMessage.Stub.asInterface(service);

//在这里对获取到的信息进行操作
  Log.i("MyConnection--onServiceConnected()", message.);

} @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub Log.i("MyConnection--onServiceDisconnected()", "message ========= null"); message = null; } } }

  

 

  

 

 

原文地址:https://www.cnblogs.com/yuanyuan-5683/p/aidl.html