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();
}
}
}
布局文件代码就不贴出了。可以下载工程自己看:
工程下载地址:点击下载
好了,搞定。一定要试着敲敲,这样印象更深刻。