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

跨进程调用Service(AIDL Service)

2016-06-29 21:40 411 查看
在Android系统中,各应用程序都运行在自己的进程中,进程之间一般无法直接进行数据交换.为了实现这种跨进程通信(inter process communication,简称 IPC),Android提供了 AIDL Service.

Android中需要AIDL (Android Interface Definition Language)来定义远程接口.

AIDL语法和java接口很相似,但存在以下几点差异:

AIDL 定义接口的源代码必须以 .aidl结尾.

AIDL接口中用到数据类型,除了基本类型,String ,List ,Map,CharSequence之外,其他类型全部需要导包,即使它们在同一个包中也需要导包.

1.创建AIDL文件

// ICat.aidl
package com.test.service.aidlservice;

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

interface ICat {

String getColor();
double getWeight();
}


义好AIDL文件后,ADT工具会自动在gen/com/example/aidlservice/目录下生成一个ICat.java接口,该类内部包含一个Stub内部类,实现了IBinder,ICat两个接口,这个Stub类会作为远程Service回调类;

2.将接口暴露给客户端

package com.test.service.aidlservice;

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

import java.util.Timer;
import java.util.TimerTask;

public class AidlService extends Service {

private CatBinder mCatBinder;
Timer mTimer = new Timer();

String[] colors = new String[]{"红色", "绿色", "蓝色"};

double[] weights = new double[]{3.3, 3.2, 1.68};

private String color;
private double weight;

public class CatBinder extends ICat.Stub {

@Override
public String getColor() throws RemoteException {
return color;
}

@Override
public double getWeight() throws RemoteException {
return weight;
}
}

@Override
public void onCreate() {
super.onCreate();

mCatBinder = new CatBinder(); //创建 CatBinder实例化对象

mTimer.schedule(new TimerTask() {
@Override
public void run() {
//随机的改变Service 组件内 color 和weight属性的值
int rand = (int) (Math.random()*3);

color = colors[rand];
weight = weights[rand];

Log.d("AidlService", "---rand---: "+rand);
}
},0,800);

}

@Override //必须实现的方法
public IBinder onBind(Intent intent) {
/**
* 返回 mCatBinder 对象
* 在绑定本地Service 的情况下,该 mCatBinder 对象会直接传给客户端的 ServiceConnection对象的 onServiceConnected 方 法的第2个参数;
*
* 在绑定远程service 的情况下,只将 mCatBinder 对象的代理传给客户端的 ServiceConnection对象的onServiceConnected方法的第2个参数;
*
*/
return mCatBinder;
}

@Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel();
}
}


在AndroidManifext.xml文件中配置该Service :

<intent-filter >
<action android:name="com.test.service.AIDL_SERVICE" />
</intent-filter>


3.客户端访问AIDLService

将Service端的AIDL文件复制到客户端中,注意要在相同的包名下。

`package com.test.aidlclient;

import android.app.Service;

import android.content.ComponentName;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import com.test.service.aidlservice.ICat;

public class AidlClientActivity extends AppCompatActivity {

private ICat catService;
Button get;
EditText color,weight;

ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {

//获取远程 Service的onBind方法返回的对象的代理
catService = ICat.Stub.asInterface(service);
}

@Override
public void onServiceDisconnected(ComponentName name) {
catService = null;
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
get = (Button) findViewById(R.id.get);
color = (EditText) findViewById(R.id.color);
weight = (EditText) findViewById(R.id.weight);

//创建所需绑定的Svice 的 Intent
Intent intent = new Intent();
intent.setAction("com.test.service.AIDL_SERVICE");
intent.setPackage(this.getPackageName()); //为了兼容 5.0版本


//绑定远程服务

bindService(intent,conn, Service.BIND_AUTO_CREATE);

get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取远程服务Service的状态
try {
color.setText(catService.getColor());
weight.setText(catService.getWeight()+"");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

@Override
protected void onDestroy() {
super.onDestroy();
//解除 绑定服务
this.unbindService(conn);
}


}

`

<客户端访问AIDL service>

AIDL 接口定义了两个进程之间的通信接口,因此不仅服务器端需要aidl接口,客户端需要定义aidl接口.因此开发客户端的第一步就是将Service端的aidl接口复制到客户端应用中,复制到客户端后ADT工具会aidl接口生成相应的实现.

客户端绑定远程service 与绑定本地service的区别并不大,同样是需要2步:

创建 ServiceConnection对象.

以 ServiceConnection对象作为参数,调用Context的 bindService()方法绑定远程Service 即可.

与绑定本地service的不同的是,绑定远程service 的ServiceConnection对象并不能直接获取Service的onBind()方法所返回的对象,它只能返回onBind()方法所返回的对象的代理,因此在 ServiceConnection的 onServiceConnected方法中需要通过如下代码进行代理:

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