尊重每个人的付出,转载请点这里 : http://blog.csdn.net/hanj456/article/details/52433718
传递基本数据类型
简单三步
Step 1
准备AIDL文件 ,注意:文件写完后需要 Sync Project一下!
package cn.test.aidlb;
interface IRemoteService {
int getResult();
void setText(String content);
}
Step 2
准备service ,要点:新建service文件后马上在清单文件中配置一下:
<service android:name=".MyService"
android:process="com.test.action">
<intent-filter>
<action android:name="com.test.action"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
服务端
public class MyService extends Service {
private static final String TAG = "MyService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
System.out.println("service onBind");
return mBinder;
}
private IRemoteService.Stub mBinder = new IRemoteService.Stub() {
@Override
public int getResult() throws RemoteException {
int sum=5*4/2;
return sum;
}
@Override
public void setText(String content) throws RemoteException {
Log.i(TAG, content+" 调用B应用的方法");
}
};
@Override
public void onCreate() {
super.onCreate();
System.out.println("service onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("service onDestroy");
}
}
Step 3
首先将service端应用中的aidl包复制到activity所在的应用中,在activity中进行绑定服务,注意:android 5.0以后 intent需要设置包名
客户单
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private IRemoteService mService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 点击按钮后绑定服务
* @param view
*/
public void bind(View view){
Intent intent = new Intent();
intent.setAction("com.test.action");
intent.setPackage("cn.test.aidlb");
bindService(intent,sc, Context.BIND_AUTO_CREATE);
}
private ServiceConnection sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IRemoteService.Stub.asInterface(service);
try {
int result = mService.getResult();
mService.setText("我在A应用 ");
Log.i(TAG, "onServiceConnected: result="+result);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
/**
* activity销毁时解绑服务
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (sc!=null){
unbindService(sc);
}
}
}
传递对象
服务端简单6步
Step1
创建对象文件Person.java,实现Parcelable接口
public class Person implements Parcelable{
private int age;
private String name;
protected Person(Parcel in) {
age = in.readInt();
name = in.readString();
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public Person() {
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
public void readFromParcel(Parcel dest) {
age = dest.readInt();
name = dest.readString();
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Step2
创建AIDL文件 Person.aidl ,声明对象为序列化
package com.xxx.xxxx;
parcelable Person;
注:parcelable第一个字母p为小写
Step3
创建AIDL接口文件 IPerson.aidl,声明传递数据需要的方法,这里需要重点说明的是数据流向的关键字声明
in ,out , inout 三者的用法和区别:简单点说就是当你的数据需要从Service端设置,Client端获取时使用out,
反之使用 in ,如果需要双向传递数据就使用 inout.
package com.test.myServer;
import com.test.myServer.Person;
interface IPerson {
String inPerson(in Person p);
String outPerson();
String inoutPerson(inout Person p);
}
Step4
这一步需要在Model下的 gradle 文件中 android 标签下加上以下内容,否则完成第五步后编译会报找不到
Person对象的错误:
sourceSets {
main {
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
Step5
新建一个service文件,要点就是实现返回我们自己定义的AIDL接口
public class AidlService extends Service {
private MyBinder mBinder;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private class MyBinder extends IPerson.Stub{
@Override
public String inPerson(Person p) throws RemoteException {
String person = "age="+p.getAge()+",name="+p.getName();
Log.i("test", "inPerson: "+person);
return person;
}
@Override
public String outPerson() throws RemoteException {
Person p = new Person();
p.setAge(22);
p.setName("Tom");
return p.toString() ;
}
@Override
public String inoutPerson(Person p) throws RemoteException {
Log.i("test", "inPerson: "+p.toString());
return p.toString();
}
}
@Override
public void onCreate() {
super.onCreate();
mBinder = new MyBinder();
}
}
Step6
在清单文件中声明创建的service文件,需要注意的是要加上action作为唯一的意图标记,最后将服务端创建的aidl文件及Person.java文件复制到客户端。
<service android:name=".AidlService">
<intent-filter>
<action android:name="com.test.myServer.action.AIDL_SERVICE"/>
</intent-filter>
</service>
再来看看客户端,这边就比较简单,重点是把服务端需要的文件复制过来之后需要clean一下project,如果在
(客户端)/build/generated/source/aidl/debug下出现service文件所在的包和aidl文件,那么恭喜你,下面
基本就没有什么难度了。
public class ComplexActivity extends AppCompatActivity{
private TextView mTv_content;
private EditText mEt_age;
private EditText mEt_name;
private IPerson mIPerson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_complex);
initView();
bind();
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mIPerson = IPerson.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mIPerson = null;
}
};
private void bind() {
Intent intent = new Intent();
intent.setAction("com.test.myServer.action.AIDL_SERVICE2");
intent.setPackage("com.test.myServer");
bindService(intent,conn, Service.BIND_AUTO_CREATE);
Log.i("test", "bind: 绑定服务");
}
private void initView() {
mTv_content = (TextView) findViewById(R.id.tv_content);
mEt_age = (EditText) findViewById(R.id.et_age);
mEt_name = (EditText) findViewById(R.id.et_name);
}
/**
* 调用aidl接口中的inPerson方法,该方法声明的数据流向是 in,
* 表示由客户端设置数据,服务端可以接收客户端传过来的数据
* @param v
*/
public void setInfo(View v){
String age = mEt_age.getText().toString().trim();
String name = mEt_name.getText().toString().trim();
try {
if (!TextUtils.isEmpty(age)&&!TextUtils.isEmpty(name)){
mIPerson.inPerson(new Person(Integer.parseInt(age),name));
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* 调用aidl接口中的outPerson方法,该方法声明的数据流向是 out,
* 表示数据流向是从服务端传输到客户端,所以在服务端中设置数据,
* 在客户端中进行显示数据
* @param v
*/
public void showInfo(View v){
try {
String content = mIPerson.outPerson();
mTv_content.setText(content);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* 调用aidl接口中的inoutPerson方法,该方法声明的数据流向是 inout,
* 表示数据是可以双向流动的,既可以在客户端设置数据从服务端取数据,
* 也可以从服务端设置数据,在客户端取数据
* @param v
*/
public void showDoubleInfo(View v){
String age = mEt_age.getText().toString().trim();
String name = mEt_name.getText().toString().trim();
try {
if (!TextUtils.isEmpty(age)&&!TextUtils.isEmpty(name)){
mIPerson.inoutPerson(new Person(Integer.parseInt(age),name));
//String content = mIPerson.inoutPerson();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}