在Android 中有一种服务说是服务其实倒不如说是一个接口,这个接口名为:Android Interface Definition Language ,这个接口可提供跨进程访问服务,英文缩写为:AIDL。

  此种服务的好处在于,多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据的共享和数据相互操作,下面将通过一个DEMO 演示AIDL 是如何为应用程序之间提供服务的。

本文大纲为:

  • 1、创建AIDL 服务端。
  • 2、创建AIDL 客户端。
  • 3、客户端调用服务端提供的服务接口。
  • 4、小结。

本文要实现的功能大致如下:创建AIDL服务端,此服务端将提供一个Student 的javabean 提供客户端取得数据,因为aidl 支持的数据类型比较简单,故这里建议把常用的数据类型的数据写入服务。

1、创建AIDL 服务端

在Android 的src 文件夹下的任意包里面新建文件,后缀名为*.aidl,如下图

输入如下代码:

package com.aidl.test;
import com.aidl.test.Student;

interface IMyService
{
Map getMap(in String test_class,in Student student);
Student getStudent();
}

Student 类是一个序列化的类,这里使用Parcelable 接口来序列化是Google 提供的一个比Serializable 效率更高的序列化类。Student 类代码如下:

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> package com.aidl.test;

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

public class Student implements Parcelable{

private int age;
private Stringname;

public int getAge(){
return age;
}

public void setAge( int age){
this .age = age;
}

public StringgetName(){
return name;
}

public void setName(Stringname){
this .name = name;
}

public static final Parcelable.Creator < Student > CREATOR = new Creator < Student > (){

@Override
public Student[]newArray( int size){
// TODOAuto-generatedmethodstub
return new Student[size];
}

@Override
public StudentcreateFromParcel(Parcelsource){
// TODOAuto-generatedmethodstub
return new Student(source);
}
};

public Student(){
}

public Student(Parcelpl){
age
= pl.readInt();
name
= pl.readString();
}

@Override
public int describeContents(){
// TODOAuto-generatedmethodstub
return 0 ;
}

@Override
public void writeToParcel(Parceldest, int flags){
// TODOAuto-generatedmethodstub
dest.writeInt(age);
dest.writeString(name);
}

}

在这里必须注意,编写javabean时必须注意如下三点:

  • 在Student 类中必须有一个静态常量,常量名必须是CREATOR,而且CREATOR 常量的数据类型必须是 Parcelable.Creator
  • 在writeToParcel 方法中需要将要序列化的值写入到 Parcel对象中。
  • 编写完Student 为时,必须再新建一个Student.aidl 文件,此文件输入以下内容:
    parcelable Student; 这里的书写是供上面我们说过的接口 *.aidl 文件导包时可以找到,并通过此文件找到Student类对象。

如果上面的步骤顺利通过的话,Android 将会自动在gen 目录下R文件的相同目录生成一个以*.aidl 文件命名的*.java 文件,如下图:

顺利生成成功后,我们再来编写一个AIDL 服务类,代码如下:

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> package com.aidl.test;

import java.util.HashMap;
import java.util.Map;

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

public class MyService extends Service{

@Override
public IBinderonBind(Intentintent){
// TODOAuto-generatedmethodstub
return new MyServiceimpl();
}

public class MyServiceimpl extends IMyService.Stub{

@Override
public StudentgetStudent() throws RemoteException{
// TODOAuto-generatedmethodstub
Studentst = new Student();
st.setAge(
18 );
st.setName(
" terry " );

return st;
}

@Override
public MapgetMap(StringtestClass,Studentstudent)
throws RemoteException{
// TODOAuto-generatedmethodstub
Map < String,Object > map = new HashMap < String,Object > ();
map.put(
" class " , " 五年级 " );
map.put(
" age " ,student.getAge());
map.put(
" name " ,student.getName());
return map;
}

}

}

如上代码,MyService 服务类有一个子类并继承自我们上面生成的*.java 文件重写其中我们在*.aidl 中声明的两个接口方法,实现了其功能。上面IBinder 必须返回此服务类的子类对象,否则客户端将无法获得服务对象。

最后,即然有服务的操作,那么就得在manifest文件中注册服务类,代码如下:

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> < service android:name =".MyService" >
< intent-filter >
< action android:name ="com.aidl.test.IMyService" ></ action >
</ intent-filter >
</ service >

至此,服务端就己经开发完成了,下面接着开发客启端。

2、创建AIDL 客户端

同样是新建一个项目,这里要注意,需要将服务端生成成功后的gen 目录下的包复制过来,放到我们新建项目的src 文件夹下,如下图:

因为IMyService 这个生成类,引用到了Student 这个javabean 所以这里一并将javabean也复制过来。

至此,客户端的创建己经完毕,下面我们就要利用创建的客户端去调用服务端的方法。

3、客户端调用服务端提供的服务接口

先看一下运行效果:

细心的朋友会发现,上面的数据不是我们在上面客户端为Student 设置的数据吗?怎么在这个程序 里面也同样得到了?没错。这就是aidl 的魅力,下面来看看如何调用 吧,图中有两个按钮,一个按钮为绑定AIDL 服务,即通过Activity 的 bindService 绑定 AIDL 外部服务,全部代码如下:

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> package com.aidl.client;

import com.aidl.test.IMyService;

import android.app.Activity;
import android.app.AlertDialog;
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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class aidlActivity extends Activity implements OnClickListener{
Buttonbtn1,btn2;

private IMyServicemyService = null ;
private ServiceConnectionserviceConnection = new ServiceConnection(){

@Override
public void onServiceDisconnected(ComponentNamename){
// TODOAuto-generatedmethodstub

}

@Override
public void onServiceConnected(ComponentNamename,IBinderservice){
// TODOAuto-generatedmethodstub
myService = IMyService.Stub.asInterface(service);
btn2.setEnabled(
true );

}
};

/** Calledwhentheactivityisfirstcreated. */
@Override
public void onCreate(BundlesavedInstanceState){
super .onCreate(savedInstanceState);
setContentView(R.layout.main);

btn1
= (Button)findViewById(R.id.Button01);
btn2
= (Button)findViewById(R.id.Button02);
btn2.setEnabled(
false );

btn1.setOnClickListener(
this );
btn2.setOnClickListener(
this );
}

@Override
public void onClick(Viewv){
// TODOAuto-generatedmethodstub
switch (v.getId()){
case R.id.Button01:
bindService(
new Intent( " com.aidl.test.IMyService " ),
serviceConnection,Context.BIND_AUTO_CREATE);
break ;
case R.id.Button02:
StringBuildersb
= new StringBuilder();
try {
sb.append(
" 学生名称为: " + myService.getStudent().getName() + " \n " );
sb.append(
" 年龄为: " + myService.getStudent().getAge() + " \n " );
sb.append(
" map对象内容为如下: "
+ myService.getMap( " 中国 " ,myService.getStudent())
.toString());
}
catch (RemoteExceptione){
// TODOAuto-generatedcatchblock
e.printStackTrace();
}

new AlertDialog.Builder(aidlActivity. this ).setTitle( " 调用外部服务 " )
.setMessage(sb.toString()).setPositiveButton(
android.R.string.ok,
null ).show();
break ;
default :
break ;
}
}
}

在ServiceConnetction里面对IMyService 进行初始化,即可操作该对象 ,该对象就可以得到我们所有要处理的数据。

4、小结

  • aidl 文件调用javabean 的aidl文件必须导包;
  • javabean 必须序列化,如果没有用javabean可以用简单的变量代替,如返回一个整型,返回一个字符串等。
  • 使用aidl 必须同时存在客户端和服务端,即客户端在本机上,服务端也在本机上,要使用客户端必须服务端事先在本机上注册过服务。

本文出自 “Terry_龙” 博客,请务必保留此出处http://terryblog.blog.51cto.com/1764499/382457

本文出自 51CTO.COM技术博客

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. Nginx系列教程(二)| 一文带你读懂Nginx的正向与反向代理
  4. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  5. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  6. android 模拟器和电脑服务器端用socket通讯
  7. Android实现长按录音松开保存、播放及根据声贝动画展示
  8. My Magic Android(安卓)Tour —— 处女作
  9. Android推送通知的实现--采用MQTT协议实现Android消息推送

随机推荐

  1. 替换Android自带apk
  2. android电源管理简要
  3. Android日期空间(DatePickerDialog)中的年
  4. Android 4.0 横竖屏切换注意事项
  5. Android Studio 1.0 官网下载链接
  6. Android拍照,上传,预览综合【修改】
  7. Android Maven 采用第三方jar包,程序运行
  8. Android ExpandableListView开发简介
  9. Ubuntu下android studio 编译报错A probl
  10. Android如何在广播接收器中启动活动和弹