android aidl唤醒客户端端怎样使用aidl对接服务端

在Android studio里面使用AIDL
在Android studio里面使用AIDL
首先我们要明白aidl的作用是什么?比如说我们提供了一个服务,当别的程序(可以看成是一个其他的进程)要来使用我们提供的服务的时候,这个时候就需要用到aidl来进行通信.至于实现的原理度娘里面有大量的文章可以参考,并不是本文重点,所以不做赘述.
首先我们先来看看实现的效果.如下图所示.我们提供了一个加法计算的服务,在客户端使用aidl连接好服务端,然后传递参数给远程服务,就可以拿到计算后的值.
是不是非常的酷炫,下面就手把手的的教你在Android studio下面如何使用aidl技术实现如下的效果.
&1.首先创建一个提供服务server App然后再创建一个访问服务的client App
2.接下来我们先对server 端的程序进行编辑.首先我们需要创建一个aidl的文件.创建目录如下图所示.这里我们创建一个名称为Calculation的aidl文件.
& &3.接着我们需要对aidl的接口文件进行编辑,我们可以提供相应的方法. &
// Calculation.aidl
package com.dapeng.
interface Calculation {
void addition(int a,int b);
& & 3.编辑好以后我们接下来生成aidl接口.首先要看看我们aidl所在的包是否是和我们清单文件的中的包名是否是一致的.如果是一致的我们直接点击rebuild parject.
& & &4.定义好aidl接口以后我们再来编辑服务端的代码.创建一个类继承service,并且在清单文件中配置好他的action,这里我们使用自己的包名去定义action.
public class CalculateService extends Service {
public CalculateService() {
public IBinder onBind(Intent intent) {
public void onCreate() {
super.onCreate();
Log.d(&--&, &onCreate&);
public void onDestroy() {
super.onDestroy();
Log.d(&--&, &onDestroy&);
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(&--&, &onStart&);
public boolean onUnbind(Intent intent) {
Log.d(&--&, &onUnbind&);
return super.onUnbind(intent);
Calculation.Stub mBinder = new Calculation.Stub() {
public int addition(int a, int b) throws RemoteException {
return a +
android:name=&.CalculateService&
android:enabled=&true&
android:exported=&true&&
&intent-filter&
&action android:name=&com.dapeng.aidldemo.CalculateService&/&
&/intent-filter&
&/service&
5.到此服务端的代码也就完成了.接着我们来写客户端的逻辑,首先是在客户端建一个和服务端的的aidl一样的包名并且将aidl接口文件放进去.然后rebuild project.
6.编辑客户端的代码进行实现.这里需要注意的是在使用隐式开启服务的时候在5.0及以上版本默认是不能直接通过action开启的,使用意图的时候加上setpackage就可以解决.
public class MainActivity extends AppCompatActivity {
private EditText etOne, etT
private TextV
private Calculation mC
private ServiceConnection mServiceC
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化界面
etOne = (EditText) findViewById(R.id.etone);
etTwo = (EditText) findViewById(R.id.ettwo);
btn = (Button) findViewById(R.id.btn);
tv = (TextView) findViewById(R.id.tv);
//连接远程服务
mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
mCalculation = Calculation.Stub.asInterface(service);
public void onServiceDisconnected(ComponentName name) {
mCalculation =
//使用意图对象绑定开启服务
Intent intent = new Intent();
intent.setAction(&com.dapeng.aidldemo.CalculateService&);
//在5.0及以上版本必须要加上这个
intent.setPackage(&com.dapeng.aidldemo&);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String s = etOne.getText().toString();
String s1 = etTwo.getText().toString();
if (TextUtils.isEmpty(s) && TextUtils.isEmpty(s1)) {
Toast.makeText(MainActivity.this, &您输入的数字不合法&, Toast.LENGTH_SHORT).show();
int addition = mCalculation.addition(Integer.parseInt(s), Integer.parseInt(s1));
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(&调用远程服务获取到的计算结果是==&);
stringBuilder.append(addition);
tv.setText(stringBuilder.toString());
} catch (RemoteException e) {
e.printStackTrace();
到此为止功能就实现.快快去体验这酷炫的功能吧.
我的热门文章
即使是一小步也想与你分享Android AIDL - 简书
Android AIDL
Android AIDL
AIDL的中文名是Android接口定义语言,用来实现进程之间的数据的共享传递。
AIDL支持的数据类型
基本数据类型(int、long、char、boolean、double等);String和CharSequence;List:只支持ArrayList,里面的每个元素都必须能够被AIDL支持;Map:只支持HashMap,里面的每个元素都必须能够被AIDL支持;Parcelable:所有实现了Parcelable接口的对象;AIDL:所有的AIDL接口本身也可以在AIDL文件中使用。除此之外,自定义的Parcelable对象和AIDL对象必须要显式import进来
AIDL接口的创建
需要创建一个包含.aidl后缀的文件,在其中声明一些接口
// IService.aidl
package com.apps.
// Declare any non-default types here with import statements
import com.apps.request.GetAppDetailR
import com.apps.ipc.IC
interface IService {
* 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);
int getAppDetail(in GetAppDetailRequest params,ICallback callback);
// ICallback.aidl
package com.apps.
// Declare any non-default types here with import statements
import android.os.B
interface ICallback {
void onResult(in Bundle result);
void onError(String code,String desc);
如果AIDL文件中引用到了自定义的Parcelable对象,必须要建一个与其同名的AIDL文件,并在其中声明为Parcelable类型
// IGetAppDetailRequest.aidl
package com.apps.
// Declare any non-default types here with import statements
parcelable GetAppDetailR
AIDL中除了基本数据类型,其他类型的参数必须标上方向:in、out或inoutin表示输入型参数out表示输出型参数inout表示输入输出参数
远程服务端Service的实现
首先需要对服务端的AIDL接口进行实现,然后在Service的onBind方法将其返回
public class IPCService extends Service {
private ServiceStub serviceS
public IBinder onBind(Intent intent) {
return serviceS
public void onCreate() {
super.onCreate();
serviceStub = new ServiceStub(this);
public class ServiceStub extends IService.Stub {
public ServiceStub(Context context){
this.context =
public ServiceStub() {
public int getAppDetail(GetAppDetailRequest params, ICallback callback) throws RemoteException {
App app = params.getApp();
if (null == app || null == callback){
Constant.AIDL_PARAMS_ERROR;
String id = app.getId();
String version = app.getVersion();
if (TextUtils.isEmpty(id) || TextUtils.isEmpty(version)){
return Constant.AIDL_PARAMS_ERROR;
getAppDetailFromNetWork(id,version,callback);
return Constant.AIDL_SUCCESS;
//模拟从网络获取数据
private void getAppDetailFromNetWork(String id,String version,ICallback callback) throws RemoteException{
//假设id为48,version为01.00.01能获得正确数据
String app_id = "48";
String app_version = "01.00.01";
if (id.equals(app_id) && version.equals(app_version)){
Bundle bundle = new Bundle();
bundle.putParcelable(Constant.CALLBACK_KEY,newAppDetailResult(id,version));
callback.onResult(bundle);
callback.onError(Constant.CALLBACK_ERROR_CODE,Constant.CALLBACK_ERROR_DESC);
private GetAppDetailResult newAppDetailResult(String id, String version){
AppDetail appDetail = new AppDetail();
App app = new App(id,version);
appDetail.setApp(app);
appDetail.setDesc("a apk about aidl");
appDetail.setDownloadTimes(48);
appDetail.setName("ipc");
GetAppDetailResult getAppDetailResult = new GetAppDetailResult();
getAppDetailResult.setAppDetail(appDetail);
getAppDetailR
由于AIDL方法是在服务端的Binder线程池执行,因此当多个客户端同时访问时,会存在多线程操作,所以需要在AIDL方法处理线程同步。
在AndroidManifest.xml文件中需要对Service进行配置
&service android:name=".IPCService"
android:enabled="true"&
&intent-filter&
&action android:name="com.apps.ipc.IPCService"&&/action&
&/intent-filter&
&/service&
客户端的实现
服务端在编译后,会在app/build/generated/source/debug下生成对应AIDL接口的java文件,需要将其以及使用到的相关的Java类一并拷贝到客户端工程,必须确保服务端与客户端这些类的包名,否则服务端客户端无法正确反序列化对方传送的数据,造成程序无法正常运行。
绑定远程服务端
通过Context的bindService方法对远程服务端进行绑定,intent设置包名是为了解决Android5.0之后需要显示调用服务的问题。
private void bindService(){
String action = "com.apps.ipc.IPCService";
String packageName = "com.apps.ipc";
Intent intent = new Intent(action);
intent.setPackage(packageName);
bindService(intent,connection, Context.BIND_AUTO_CREATE);
ServiceConnection用于处理客户端与服务端的连接、断开处理。当绑定服务成功后会回调执行onServiceConnected方法,表示已经连接上服务端,然后将服务端返回的Binder对象转换成AIDL接口,之后就可以通过这个接口去调用服务端的方法。当服务端因异常或者主动断开后,会执行onServiceDisConnected方法,表示已经断开连接。
private IS
private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
MainActivity.this.service = IService.Stub.asInterface(service);
result.setText("Service is connected");
public void onServiceDisconnected(ComponentName name) {
MainActivity.this.service =
result.setText("Service is disconnected");
private ICallback.Stub callback = new ICallback.Stub(){
public IBinder asBinder() {
return super.asBinder();
public void onResult(Bundle bundle) throws RemoteException {
bundle.setClassLoader(GetAppDetailResult.class.getClassLoader());
GetAppDetailResult getAppDetailResult = bundle.getParcelable(Constant.CALLBACK_KEY);
AppDetail appDetail = getAppDetailResult.getAppDetail();
App app = appDetail.getApp();
//定义了一个TextView用于显示结果
result.setText("id:" + app.getId() + ",version:" + app.getVersion() + ",name:" + appDetail.getName()
+ ",desc:" + appDetail.getDesc() + ",downlaodTimes:" + appDetail.getDownloadTimes());
public void onError(String code, String desc) throws RemoteException {
result.setText("error:" + code + ",message:" + desc);
private void getAppDetail(String id,String version){
if (null != service){
GetAppDetailRequest getAppDetailRequest = new GetAppDetailRequest();
getAppDetailRequest.setApp(new App(id,version));
int ret = service.getAppDetail(getAppDetailRequest,callback);
if (ret == Constant.AIDL_PARAMS_ERROR){
result.setText("request params error");
} catch (RemoteException e) {
e.printStackTrace();
image1.png
image2.png

我要回帖

更多关于 客户端和服务端的区别 的文章

 

随机推荐