AIDL的使用
实现步骤:
1.首先建立服务端。在src-main目录下建立aidl文件夹,在其中创建一个包然后aidl文件。
IMyAidlInterface.aidl
// IMyAidlInterface.aidl
package com.csht.aidl;
import com.csht.aidl.Person;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
int add(int arg1, int arg2);
Person getPerson();
}
说明:
1.int add()方法用来计算两位数之和。
2.getPerson(),用来获得传递的对象。
Person.aidl
// Person.aidl
package com.csht.aidl;
// Declare any non-default types here with import statements
parcelable Person;
Person
package com.csht.aidl;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by Administrator on 2017-10-23.
*/
public class Person implements Parcelable{
private String name;
private int age;
private Person(Parcel in)
{
readFromParcel(in);
}
private void readFromParcel(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 在想要进行序列号传递的实体类内部一定要声明该常量。常量名只能是CREATOR,类型也必须是
* Parcelable.Creator<T> T:就是当前对象类型
*/
public static final Creator<Person> CREATOR = new Creator<Person>() {
/***
* 根据序列化的Parcel对象,反序列化为原本的实体对象
* 读出顺序要和writeToParcel的写入顺序相同
*/
@Override
public Person createFromParcel(Parcel in) {
return new Person(in.readString(),in.readInt());
}
/**
* 创建一个要序列化的实体类的数组,数组中存储的都设置为null
*/
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
/**
* 将对象写入到Parcel(序列化)
* @param dest:就是对象即将写入的目的对象
* @param flags: 有关对象序列号的方式的标识
* 这里要注意,写入的顺序要和在createFromParcel方法中读出的顺序完全相同。例如这里先写入的为name,
* 那么在createFromParcel就要先读name
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
注意:aidl中自定义类类名一定要保证一样,否则很蛋疼(项目一clean就报错,找了半天,坑死了)。
服务端:
目录结构:
MyService
package com.csht.aidl_service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import com.csht.aidl.IMyAidlInterface;
import com.csht.aidl.Person;
/**
* Created by Administrator on 2017-10-23.
*/
public class MyServer extends Service {
Person person;
IMyAidlInterface.Stub mStub = new IMyAidlInterface.Stub() {
@Override
public int add(int arg1, int arg2) throws RemoteException {
return arg1 + arg2;
}
@Override
public Person getPerson() throws RemoteException {
return person;
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
person = new Person("吕布", 18);
return mStub;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.csht.aidl_service">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name=
"android.intent.action.MAIN" />
<category android:name=
"android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyServer">
<intent-filter>
<action android:name="com.csht.myService" />
</intent-filter>
</service>
</application>
</manifest>
将服务端main下的aidl复制到客户端。
客户端:
目录结构:
MainActivity
package com.csht.aidl_client;
import android.app.Activity;
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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.csht.aidl.IMyAidlInterface;
import com.csht.aidl.Person;
public class MainActivity extends Activity implements View.OnClickListener {
TextView textView;
Button btn_aidl;
IMyAidlInterface mStub;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
btn_aidl = (Button) findViewById(R.id.btn_aidl);
btn_aidl.setOnClickListener(this);
Intent intent = new Intent();
//android 5.0以后直设置action不能启动相应的服务,需要设置packageName或者Component。
intent.setAction("com.csht.myService");
intent.setComponent(newComponentName(
"com.csht.aidl_service", "com.csht.aidl_service.MyServer"));
//绑定服务
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.btn_aidl) {
if (mStub != null) {
try {
int value = mStub.add(1, 8);
Person person = mStub.getPerson();
if (null != person){
textView.setText(value + " 姓名:" + person.getName() + "年龄:" + person.getAge());
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mStub = IMyAidlInterface.Stub.asInterface(iBinder);
if (mStub == null) {
Log.e("AAA", "the mStub is null");
} else {
Log.e("AAA", "the mStub 不为空");
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onPause() {
super.onPause();
//解绑服务
unbindService(serviceConnection);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
注意:在使用aidl传递对象时,如果遇到过找不到aidl中自定义的类,需要在build.gradle中,添加一下代码:
/**
* 加上sourceSets中内容,否则找不到aidl中的实体类
*/
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/aidl']
resources.srcDirs = ['src/main/java', 'src/main/aidl']
aidl.srcDirs = ['src/main/aidl']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
}
添加后build.gradle代码如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "com.csht.aidl_client"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
/**
* 加上sourceSets,否则找不到aidl中的实体类
*/
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/aidl']
resources.srcDirs = ['src/main/java', 'src/main/aidl']
aidl.srcDirs = ['src/main/aidl']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta3'
testCompile 'junit:junit:4.12'
}
首先安装服务端,然后运行客户端。
效果如下:
demo下载地址:http://download.csdn.net/download/dream_xang/10036254