AIDL详解
来源:互联网 发布:森田疗法 知乎 编辑:程序博客网 时间:2024/05/16 19:21
一、概述
AIDL是Android Interface Definition Language,即Android接口定义语言。设计这门语言的目的主要是为了是:进程间通信。在Android中,每一个进程都是单独的一个Dalvik VM实例,拥有自己独立的内存,存储数据,执行操作。AIDL就是负责定义一些两个进程间相互认可的通信规则,用来传输数据,沟通交流。
二、语法
- 文件类型:用AIDL书写的文件后缀是.aidl,而不是.java。
- 导包:使用AIDL只是的数据类型不需要导包,使用自己定义的实体类型,即使引用的实体与使用的类在同一个包下面,也要导报。列入demo中Course.java与CourseManager.aidl同在com.gyg.aidlclient下面,在CourseManager.aidl中使用Course.java也要import com.gyg.aidlclient.Course;(这个好像要手动导入,负责编译的时候会报错)。
- 数据类型:默认支持的数据类型:
*Java中的八种基本数据类型:byte,short,int,long,float,double,boolean,char。
*String类型
*CharSequence
*List list中的所有元素必须AIDL支持的类型之一,或一个其它AIDL生成的接口,或定义的parcelable。支持泛型。
*Map map中的所有元素必须是AIDL支持的类型之一,或一个其它AIDL生成的接口,或定义的parcelable。不支持泛型。 - 定向tag
*in 数据流向从客户端到服务端,服务端接收到客户端的一个完整对象,客户端接收到服务端一个空的对象。
*out 数据流向从服务端到客户端,服务端接收到客户端的一个空对象,客户端接收到服务端一个完整对象。
*inout 数据流向双向,服务端接收到客户端的一个完整对象,客户端接收到服务端的一个完整对象。 - 两种.aidl
* 定义parcelable对象,供其它aidl文件使用非默认的数据类型。例如demo中的Course.aidl。
* 定义方法接口,用来完成跨进程数据通信的。例如demo中的CourseManager.aidl。
三、示例代码
1、自定义实体类Course.java,继承自parcelable接口
public class Course implements Parcelable { private String name;//课程名称 private double credit;//课程学分 private String teacher;//课程教师 public Course() { } public Course(String name, double credit, String teacher) { this.name = name; this.credit = credit; this.teacher = teacher; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getCredit() { return credit; } public void setCredit(double credit) { this.credit = credit; } public String getTeacher() { return teacher; } public void setTeacher(String teacher) { this.teacher = teacher; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(this.name); dest.writeDouble(this.credit); dest.writeString(this.teacher); } public void readFromParcel(Parcel dest) { name = dest.readString(); credit=dest.readDouble(); teacher=dest.readString(); } protected Course(Parcel in) { this.name = in.readString(); this.credit = in.readDouble(); this.teacher = in.readString(); } public static final Parcelable.Creator<Course> CREATOR = new Parcelable.Creator<Course>() { @Override public Course createFromParcel(Parcel source) { return new Course(source); } @Override public Course[] newArray(int size) { return new Course[size]; } }; @Override public String toString() { return "Course{" + "name='" + name + '\'' + ", credit=" + credit + ", teacher='" + teacher + '\'' + '}'; }}
2、定义Course.aidl,供其它aidl文件使用Course对象。
/**注意:Course.java和Course.aidl的包名应该是一样的。这里有两种方法:1.将Course.java放到与Course.aidl同一个包下,然后在module的build.gradle里面添加 sourceSets { main { java.srcDirs = ['src/main/java', 'src/main/aidl'] } } 2.将Course.java放在java目录下与Course.aidl的同一目录名下。build.gradle不需要任何设置。*/package com.gyg.aidlclient;parcelable Course;
3.定义CourseManager.aidl,定义接口间通信的规则
// CourseManager.aidlpackage com.gyg.aidlclient;import com.gyg.aidlclient.Course;// Declare any non-default types here with import statementsinterface CourseManager { Course getCourse();//从服务器获取一个Course对象 Course updateCourseIn(in Course course);//in方式传一个Course对象到服务器端,并接受服务器端返回的Course对象 Course updateCourseOut(out Course course);//out方式传一个Course对象到服务器端,并接受服务器端返回的Course对象 Course updateCourseInOut(inout Course course);//inout方式传一个Course对象到服务器端,并接受服务器端返回的Course对象}
3、将aidl目录的文件原封不懂的复制到服务器端下面,(服务器端aidl文件的包名要一致,否则会编译错误);
4、服务端编写AIDLService.java
package com.gyg.aidlserver;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;import com.gyg.aidlclient.Course;import com.gyg.aidlclient.CourseManager;/** * Created by gyg on 2017/2/14. */public class AIDLService extends Service{ private final CourseManager.Stub mCourseManager=new CourseManager.Stub(){ @Override public Course getCourse() throws RemoteException { return new Course("Android高级开发",17.3,"Jack");//创建并返回一个Course对象给客户端,在客户端查看是否接受到该对象,接收到则表明两个进程间成功通信 } /** * in方式接受一个Course对象,并 * @param course * @return * @throws RemoteException */ @Override public Course updateCourseIn(Course course) throws RemoteException { if (course==null){ course=new Course(); } System.out.println("服务端In:"+course); course.setCredit(233.3); return course; } @Override public Course updateCourseOut(Course course) throws RemoteException { if (course==null){ course=new Course(); } System.out.println("服务端Out:"+course); course.setCredit(233.3); return course; } @Override public Course updateCourseInOut(Course course) throws RemoteException { if (course==null){ course=new Course(); } System.out.println("服务端InOut:"+course); course.setCredit(177.77); return course; } }; @Nullable @Override public IBinder onBind(Intent intent) { return mCourseManager;//返回mCourseManager给客户端,客户端利用mCourseManager与服务端进行通信 }}
5、AndroidManifest.xml中注册AIDLService.java
<!--注意android:exported="true"一定要添加,否则客户端链接不到Service--> <service android:name=".AIDLService" android:exported="true" > <intent-filter> <action android:name="com.gyg.aidl"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </service>
6、客户端编写测试代码:
package com.gyg.aidlclient;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.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private CourseManager mCourseManager; Course originCourse;//服务器端返回的Course对象 private boolean mBound=false;//记录service是否连接 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.updateIn).setOnClickListener(this); findViewById(R.id.updateOut).setOnClickListener(this); findViewById(R.id.updateInOut).setOnClickListener(this); } @Override protected void onStart() { super.onStart(); if (!mBound){ connectService();//绑定service } } @Override protected void onStop() { super.onStop(); if (mBound=true){ unbindService(mServiceConnection);//解绑service } } private ServiceConnection mServiceConnection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { mCourseManager=CourseManager.Stub.asInterface(iBinder); Log.d(getLocalClassName(),"Service Connected"); if (mCourseManager!=null){ try { originCourse=mCourseManager.getCourse();//获取服务器返回的Course对象 ((TextView)findViewById(R.id.originTxt)).setText(originCourse.toString());//显示服务器返回的对象数据 } catch (RemoteException e) { e.printStackTrace(); } } mBound=true; } @Override public void onServiceDisconnected(ComponentName componentName) { Log.d(getLocalClassName(),"Service UnConnected"); mBound=false; } }; //隐式链接AIDLService private void connectService(){ Intent intent=new Intent(); intent.setAction("com.gyg.aidl"); intent.setPackage("com.gyg.aidlserver"); bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.updateIn://测试in方式返回的数据 if (mCourseManager!=null){ try { mCourseManager.updateCourseIn(originCourse); ((TextView)findViewById(R.id.inTxt)).setText("定向IN:"+originCourse.toString());//显示定向in后originCourse数据 } catch (RemoteException e) { e.printStackTrace(); } } break; case R.id.updateOut://测试out方式返回的数据 if (mCourseManager!=null){ try { mCourseManager.updateCourseOut(originCourse); ((TextView)findViewById(R.id.outTxt)).setText("定向OUT:"+originCourse.toString());//显示定向out后originCourse数据 } catch (RemoteException e) { e.printStackTrace(); } } break; case R.id.updateInOut: if (mCourseManager!=null){//测试inout方式返回的数据 try { mCourseManager.updateCourseInOut(originCourse); ((TextView)findViewById(R.id.inoutTxt)).setText("定向INOUT:"+originCourse.toString());//显示定向inout后originCourse数据 } catch (RemoteException e) { e.printStackTrace(); } } break; } }}
四、测试结果分析
1.首先运行AIDLServer,再运行AIDLClient,成功后运行结果如下:
说明AIDLClient与AIDLServer通信成功,成功获得到AIDLServer传过来的数据
2.点击UPDATEIN按钮,服务器端输出结果:
服务器接收到客户端的一个完整对象
客户端输出结果:
服务器端的数据对客户端的数据没有影响
3.点击UPDATEOUT,服务器端结果:
服务器端接收到客户端的一个空对象
客户端结果:
客户端因为服务器端的数据的改变而更改了。
4.点击UPDATEINOUT按钮:
服务器端结果:
客户端接收到服务端的完整对象
客户端结果:
客户端因为服务端数据的变化而发生了更改。
五、demo
- AIDL详解
- AIDL详解
- AIDL详解
- AIDL详解
- 什么是aidl?Android AIDL详解
- 什么是aidl?Android AIDL详解
- 什么是aidl?Android AIDL详解
- AIDL详解之AIDL基础
- Android AIDL使用详解
- Android AIDL详解_1
- Android AIDL详解_2
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- android AIDL实现详解
- C#串口通信
- HDU 1024 Max Sum Plus Plus (基础dp)
- Gradle 的Daemon配置
- Linux下的FILE结构体
- Babel转码工具使es6\es7向es5转码
- AIDL详解
- linux下sublimetext的中文输入问题解决方法
- App优化之提升你的App启动速度之实例挑战
- Hadoop实践(零)---Hadoop项目生态系统
- 经典图像 HOG 特征
- Nginx详细配置的备注说明
- 那些年,我使用过的轮子
- Android开发——减小APK大小
- POJ 35588 The Downloading Task 可能会