您的位置:首页 > 移动开发 > Android开发

android AIDL实现进程间的通信

2016-05-23 13:43 661 查看
android service作为四大组件之一,实现进程通讯,以及相关的服务。以一个简单的实例为主。

目的:掌握service+adil的简单通讯。

实例要求:编写两个程序,使用AIDL实现远程服务通信。一个作为服务器,一个作为客服端,服务器端提供数据,数据对象为自定义的person。

完成效果图:



服务器端和客户端程序都需安装上,否则客户端无法获取数据。

service端的实现



其中*.aidl为AIDL的文件,是android系统提供的一种本地语言编写方式。

我们来看看这文件中都是什么:

Person.adil

package com.example.aidl;
parcelable Person;


看看这么写的原因:自定义的类必须实现 Parcelable 接口。Parcelable是android提供的一个比serializable效率更高的序列号接口(自行查看帮助文档,内有示例代码,注意读出顺序要和writeToParcel的写入顺序相同),还需要创建一个Person.aidl文件来声明你的parcelable 类。

UserInfo.aidl

package com.example.aidl;
import com.example.aidl.Person;
interface UserInfo{
List<Person> getPersonList();
}


有没发现很简单,而且和java的风格很像,没错只要将写好的*.java给出后缀名为aidl即可。

Person类的实现

注意其中Parcelable的实现

public class Person implements Parcelable {
public static final Creator<Person> CREATOR = new Parcelable.Creator<Person>() {

@Override
public Person createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new Person(source);
}

@Override
public Person[] newArray(int size) {
// TODO Auto-generated method stub
return new Person[size];
}
};

private Person(Parcel in) {
name = in.readString();
age = in.readInt();
sex = in.readString();
}

private String name;
private int age;
private String sex;

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

@Override
public int describeContents() {

return 0;
}

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

public String toString() {
return "姓名:" + name + " 年龄:" + age + "      性别:" + sex;
}
}


service的简单实现

public class MyService extends Service {
private List<Person> plist = new ArrayList<Person>();

public MyService() {
plist.add(new Person("张三", 4, "男"));
plist.add(new Person("李四", 5, "女"));
}

private Binder mBinder = new UserInfo.Stub() {
@Override
public List<Person> getPersonList() throws RemoteException {
// TODO Auto-generated method stub
return plist;
}

};

@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
}


这里简单起见,之间存入两个person实例。

最后别忘了在AndroidManifest.xml中声明你的服务:

<service android:name=".MyService" >
<intent-filter>
<action android:name="com.example.AIDLCommunicationService.MyService" />
</intent-filter>
</service>


好了service端的基本实现了。有些不懂的地方可以再网上搜搜。

接下来是客户端的实现

client:



可以看到com.example.aidl中的东西和service中的一模一样,所有可以直接冲service中复制过来,因此我们要记住在是些类似的远程通讯的时候,关于aidl的部分最好反正一个包中,方便使用。

剩下的就是主函数从服务端中获取数据了。

看看代码

public class MainActivity extends Activity {
private TextView tv_show;
private Button bn_getData, bn_conn;
private UserInfo userInfo;
private Intent intent;
private boolean haveConnection = false;
private ServiceConnection mConnection = new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName name) {

}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
userInfo = UserInfo.Stub.asInterface(service);
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent("com.example.AIDLCommunicationService.MyService");
intent.setPackage("com.example.AIDLCommunicationService");
init();
}

private void init() {
tv_show = (TextView) findViewById(R.id.tv_content);
bn_getData = (Button) findViewById(R.id.bn_getData);
bn_conn = (Button) findViewById(R.id.bn_connetion);
}

public void connection(View v) {
if (!haveConnection) {
try {
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
haveConnection = true;
bn_getData.setClickable(true);
tv_show.setText("已连接");
bn_conn.setText("断开");
} catch (Exception e) {
bn_getData.setClickable(false);
e.printStackTrace();
}
} else {
unbindService(mConnection);
haveConnection = false;
bn_conn.setText("连接");
bn_getData.setClickable(false);
}
}

public void getData(View v) {
try {
List<Person> plist = userInfo.getPersonList();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < plist.size(); i++) {
sb.append(plist.get(i).toString() + "\n");
}
tv_show.setText(sb.toString());
} catch (RemoteException e) {
tv_show.setText("获取失败,可能服务器,没开。");
e.printStackTrace();
}
}
}


布局文件代码就不贴出了。可以下载工程自己看:

工程下载地址:点击下载

好了,搞定。一定要试着敲敲,这样印象更深刻。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息