您的位置:首页 > 大数据 > 人工智能

AIDL笔记

2016-03-09 15:54 423 查看

AIDL

1. 什么是AIDL

AIDL(Android Interface Definition Language,即Android接口定义语言。)

IPC(Inter-Process Communication,进程间通信)。

在进程间通信不一定需要AIDL,因为两个进程间不能直接通信,需要Android系统底层间接实现通信,所以比较耗资源,能不用就不用。如下图:



进程间通讯可以分为下面几种:

AIDL

在IPC时,并且多个应用,多线程时才用到。

Binder

只有IPC,多个应用,没有多线程

Messager

只有IPC,没有多线程

2. 创建AIDL

官方文档上的例子:

// IRemoteService.aidl,//包名,文件必须放在指定的目录
package com.example.android;

// Declare any non-default types here with import statements

/** Example service interface */
interface IRemoteService {
/** Request the process ID of this service, to do evil things with it. */
int getPid();

/** 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);
}


官方文档上写AIDL支持的数据类型包括:

所有的基本数据类型;

String ,CharSequence

List,Map

实际上基本数据类型的short类型不被支持,编译都通不过。

还有Parcelable(序列化)。

Parcelable(序列化)

那AIDL文件我们怎么转成java文件呢?在sdk\build-tools\23.0.2(版本)下有个aidl.exe文件,我们就是用这个来转成java文件:

输入命令:aidl IRemoteService.aidl


就会生成一个同名的java文件。

在eclipse中创建AIDL

新建一个Android项目后,直接在java文件中new一个aidl文件



在eclipse中自动编译生成java,而java就和R文件在一起:



这样就可以直接在Activity中提示出来了



在Android studio中创建AIDL

而Android studio中和eclipse有点不同,是和java同级目录创建





编译后生成的java文件:


3. 下面用一个案例

客户端传两个数字,调用服务端的计算方法求和

首先服务端的AIDL文件代码:

package com.hou.aidl;

interface IMyAidlInterface {

int add(int num1,int num2);
}


然后服务端需要远程Service,代码:

package com.hou.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class IRemoteService extends Service {
//当客户端绑定服务时,会返回iBinder对象
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}

private IBinder iBinder = new IMyAidlInterface.Stub() {

@Override
public int add(int num1, int num2) throws RemoteException {
Log.e("111", "收到了远程传过来的值" + num1 + "和" + num2);
return num1 + num2;
}
};
}


note:需要在清单文件中注册,并添加intent-filter

<service android:name=".IRemoteService">
<intent-filter>
<action android:name="com.hou.aidl.client" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>


客户端:

package com.hou.aidlclient;

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.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.hou.aidl.IMyAidlInterface;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private EditText et_num1;
private EditText et_num2;
private EditText et_sum;
private Button btn_sum;
private IMyAidlInterface iMyAidlInterface;
private ServiceConnection conn = new ServiceConnection() {
//服务绑定上的时候
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("111", "绑定服务成功==" + name);
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}

//服务断开的时候
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("111", "服务断开连接==" + name);
iMyAidlInterface = null;
}

};

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

initView();
bindAidlService();
}

private void initView() {
et_num1 = (EditText) findViewById(R.id.et_num1);
et_num2 = (EditText) findViewById(R.id.et_num2);
et_sum = (EditText) findViewById(R.id.et_sum);
btn_sum = (Button) findViewById(R.id.btn_sum);
btn_sum.setOnClickListener(this);
}

@Override
public void onClick(View v) {
int num1 = Integer.parseInt(et_num1.getText().toString());
int num2 = Integer.parseInt(et_num2.getText().toString());
try {
int sum = iMyAidlInterface.add(num1, num2);
et_sum.setText(sum + "");
} catch (RemoteException e) {
et_sum.setText("出错了");
e.printStackTrace();
}
}

//绑定服务
private void bindAidlService() {
Intent intent = new Intent();
//在Android5.0以后只能已显示intent方式启动 绑定服务
intent.setComponent(new ComponentName("com.hou.aidl", "com.hou.aidl.IRemoteService"));
//        Intent intent = new Intent("com.hou.aidl.client");//隐式意图方式
bindService(intent, conn, Context.BIND_AUTO_CREATE);//Context.BIND_AUTO_CREATE自动创建
}

@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
}


现在就可以使用了,启动服务端,打开客户端就可以求和计算。

当然除过上边提到的类型外,我们经常会传递自定义类型的数据,比如一个对象Person。

服务端:

创建一个Person对象,实现Parcelable序列化:

package com.hou.aidl;

import android.os.Parcel;
import android.os.Parcelable;

/**
* Created by hp on 2016/3/9.
*/
public class Person implements Parcelable {

public String name;
public int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

protected Person(Parcel in) {
//必须和writeToParcel中写入的顺序一致;
name = in.readString();
age = in.readInt();
}

public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}

@Override
public Person[] newArray(int size) {
return new Person[size];
}
};

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}


创建Person.aidl

package com.hou.aidl;

parcelable  Person;


package com.hou.aidl;
//需要引入Person
import com.hou.aidl.Person;
interface IMyAidlInterface {

List<Person> add(in Person person);
}


Service:

package com.hou.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import java.util.ArrayList;
import java.util.List;

public class IRemoteService extends Service {

List<Person> persons;

//当客户端绑定服务时,会返回iBinder对象
@Override
public IBinder onBind(Intent intent) {
persons = new ArrayList<>();
return iBinder;
}

private IBinder iBinder = new IMyAidlInterface.Stub() {
@Override
public List<Person> add(Person person) throws RemoteException {
persons.add(person);
return persons;
}
};
}


客户端:

把IMyAidlInterface.aidl和Person.aidl都复制到客户端同名包下(aidl-com.hou.aidl)

把Person复制到客户端同名包下(com.hou.aidl)

package com.hou.aidlclient;

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.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.hou.aidl.IMyAidlInterface;
import com.hou.aidl.Person;

import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button btn_sum;
private IMyAidlInterface iMyAidlInterface;
private ServiceConnection conn = new ServiceConnection() {
//服务绑定上的时候
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("111", "绑定服务成功==" + name);
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}

//服务断开的时候
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("111", "服务断开连接==" + name);
iMyAidlInterface = null;
}

};

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

initView();
bindAidlService();
}

private void initView() {
btn_sum = (Button) findViewById(R.id.btn_sum);
btn_sum.setOnClickListener(this);
}

@Override
public void onClick(View v) {
try {
List<Person> persons = iMyAidlInterface.add(new Person("李四", 18));
Person person = persons.get(0);
et_sum.setText(person.toString());
} catch (RemoteException e) {
et_sum.setText("出错了");
e.printStackTrace();
}
}

//绑定服务
private void bindAidlService() {
Intent intent = new Intent();
//在Android5.0以后只能已显示intent方式启动 绑定服务
intent.setComponent(new ComponentName("com.hou.aidl", "com.hou.aidl.IRemoteService"));
//        Intent intent = new Intent("com.hou.aidl.client");//隐式意图方式
bindService(intent, conn, Context.BIND_AUTO_CREATE);//Context.BIND_AUTO_CREATE自动创建
}

@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
}


AIDL原理图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: