什么是AIDL?
AIDL是 Android Interface definition language的缩写,它是一种Android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口
AIDL可以解决什么问题?
- 可以实现多个应用程序共享同一个Service的功能,比如:IM服务可以提供给多个APP使用,先在推送基本都是采取这种方案
 - 可以跨进程调用服务里的方法
 
搭建了简单的Service框架
1.继承Service
public class PushService extends Service{
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
}2.在AndroidManifest.xml里注册
<?xml version="1.0" encoding="utf-8"?>  | 
建立AIDL
创建AIDL文件
 

编写AIDL文件
interface IHandler {
  void connect();
}aidl生成后的样子
 

编写客户端 ServiceConnection
public class PushClient {
    private IHandler iHandler;
    private static PushClient instance = new PushClient();
    public static PushClient getInstance() {
        return instance;
    }
    public void init(Application app){
        Intent binderIntent = new Intent(app,PushService.class);
        app.bindService(binderIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iHandler = IHandler.Stub.asInterface(service);
            //连接成功调用
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            //断开连接调用
        }
    };
    //通过AIDL远程调用
    public void connect(){
        try {
            iHandler.connect();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
} 
写服务端实现connect方法
 
public class LibHandler extends IHandler.Stub{
    @Override
    public void connect() throws RemoteException {
    }
    @Override
    public IBinder asBinder() {
        return null;
    }
}  
测试
 
 
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();
    }
    private void init() {
      findViewById(R.id.aidl_test).setOnClickListener(this);
    }
    @Override
    public void onClick(View view) {
        PushClient.getInstance().connect();
    }
}  
其实到这里我们就结束了。 
 
接下来我们看看如果自定义传递的数据类型
 
传递自定义的类型
AIDL默认支持的类型包括Java基本类型(int、long、boolean等),和(String、List、Map、CharSequence),如果要传递自定义的类型需要实现android.os.Parcelable接口。  
 
 
自定义Message实体:
 
public class Message implements Parcelable {
    private long id;
    private String content;
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", content='" + content + '\'' +
                '}';
    }
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.id);
        dest.writeString(this.content);
    }
    protected Message(Parcel in) {
        this.id = in.readLong();
        this.content = in.readString();
    }
    public static final Creator<Message> CREATOR = new Creator<Message>() {
        @Override
        public Message createFromParcel(Parcel source) {
            return new Message(source);
        }
        @Override
        public Message[] newArray(int size) {
            return new Message[size];
        }
    };
}  
修改IHandler  
 
interface IHandler {
  void connect();
  void sendMessage(Message message);
} 
 

 
注意: 自定类型aidl文件名字、路径需要和自定义类名字、路径保持一致,
 
编译一下,发现报了个错
 

 
意思是必须定义Message的方向,AIDL 参数有方向。(学习了)
 如果sendMessage方法的message参数是纯粹的输入参数—这意味着是从客户端到服务器的数据,你需要在AIDL声明:
 
void sendMessage(in Message message);
  如果
  sendMessage
  方法的
  message
  参数是纯粹的输出-这意味着它的数据是通过从服务器到客户端,使用:
 
void sendMessage(out Message message);
  如果
  sendMessage
  方法的
  message
  参数是输入也是输出-客户端的值在服务可能会修改,使用:
  
void sendMessage(inout Message message);
我们这里是客户端范围服务端的数据,所以用in  
interface IHandler {
  void connect();
  void sendMessage(in Message message);
}  
好了,aidl的用法就到这里了,aidl主要是用在跨进程间通信和数据交换,平时开发中也用的比较少,通过这个例子加深了对他的用法,后面有什么好的坑,我会发出了的,谢谢大家。最后做个链接   
https://github.com/xiangzhihong/aidl 
 










