Android中AIDL使用详解
2018-02-27 15:58
507 查看
简介
AIDL:Android Interface Definition Language,即Android接口定义语言,用于生成Android不同进程间进行进程通信(IPC)的代码,一般情况下一个进程是无法访问另一个进程的内存的。如果某些情况下仍然需要跨进程访问内存数据,这时候Android系统就要将其对象分解成能够识别的原数据,编写这一组操作的代码是一项繁琐的工作,但是AIDL对底层进行了抽象的封装,简化了跨进程操作。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
接下来介绍在AndroidStudio中使用ALDL在进程间通讯(也就是两个应用的通讯)分别从服务端和客户端两个方面
1. 服务端:
服务端首先要创建一个Service用来监听客户端的连接请求,然后创建ALDL文件,将暴露给客户端的接口在这个ALDL文件的申明,最后在Service中实现这个ALDL的接口实现
2. 客户端:
客户端首先需要绑定服务端的Service,绑定成功之后,将服务器返回的Binder对象转换成ALDL接口所属的类型,接着就可以调用ALDL中的方法
3. ALDL接口的创建:
首先看ALDL接口的创建,如下所示,我们创建
自定义类要实现Parcelable
服务端的ALDL部署
![](https://img-blog.csdn.net/20180227152143660?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2t5MTM3MzUxNjkwOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
下面是两个ALDL文件
Book.aidl
IBookManger.aidl
运行你的aidl会报错,log显示找不到Book的定义,没错现在你的Book在aidl包下,编译时不会去它下面找类,此时你需要做以下工作,在build.gradle文件中加入以下代码。。
编译成功之后会出现
![](https://img-blog.csdn.net/20180227155322854?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2t5MTM3MzUxNjkwOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
ALDL文件支持的格式那些数据类型呢?如下所示
基本数据类型
String和CharSequence
list:只支持ArrayList,里面的每个元素都必须能够被ALDL支持
Map:只支持HashMap,里面的每个元素都必须被ALDL支持,包括key和value
Parcelable:所有实现了Parcelable的对象
ALDL:所有ALDL接口本身也可以在ALDL文件中使用
注意
1.ALDL中除了基本数据类型,其他类型的参数必须表上方向:in 、out、inout,in表示输入型参数,out表示输出型参数,inout表示输入输出型参数
2. ALDL接口中只支持方法,不支持声明静态变量,
3.为了方便ALDL开发,建议将所有和ALDL相关的类和文件全部放入同一个包中,这样我们可以直接将整个包复制到客户端工程中,ALDL包的结构在客户端和服务端保持一致,否则会错。因为客户端要反序列化服务端中和ALDL接口相关的所有类,如果类的完整路径不对就无法成功反序列化。
4.远程服务端Service的实现
Service的注册
5.客户端的实现
最后贴上运行之后的效果
AIDL:Android Interface Definition Language,即Android接口定义语言,用于生成Android不同进程间进行进程通信(IPC)的代码,一般情况下一个进程是无法访问另一个进程的内存的。如果某些情况下仍然需要跨进程访问内存数据,这时候Android系统就要将其对象分解成能够识别的原数据,编写这一组操作的代码是一项繁琐的工作,但是AIDL对底层进行了抽象的封装,简化了跨进程操作。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
接下来介绍在AndroidStudio中使用ALDL在进程间通讯(也就是两个应用的通讯)分别从服务端和客户端两个方面
1. 服务端:
服务端首先要创建一个Service用来监听客户端的连接请求,然后创建ALDL文件,将暴露给客户端的接口在这个ALDL文件的申明,最后在Service中实现这个ALDL的接口实现
2. 客户端:
客户端首先需要绑定服务端的Service,绑定成功之后,将服务器返回的Binder对象转换成ALDL接口所属的类型,接着就可以调用ALDL中的方法
3. ALDL接口的创建:
首先看ALDL接口的创建,如下所示,我们创建
自定义类要实现Parcelable
服务端的ALDL部署
/** *自定义类型 **/ public class Book implements Parcelable { private int bookId; private String bookName; public Book(int bookId, String bookName) { this.bookId = bookId; this.bookName = bookName; } public int getBookId() { return bookId; } public void setBookId(int bookId) { this.bookId = bookId; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.bookId); dest.writeString(this.bookName); } public Book() { } protected Book(Parcel in) { this.bookId = in.readInt(); this.bookName = in.readString(); } public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() { @Override public Book createFromParcel(Parcel source) { return new Book(source); } @Override public Book[] newArray(int size) { return new Book[size]; } }; @Override public String toString() { return "Book{" + "bookId=" + bookId + ", bookName='" + bookName + '\'' + '}'; } }
下面是两个ALDL文件
Book.aidl
// Book.aidl package com.example.administrator.wuandy; // Declare any non-default types here with import statements //ALDL中使用自定义的Parcelable为其声明类型 parcelable Book;
IBookManger.aidl
// IBookManger.aidl package com.example.administrator.wuandy; import com.example.administrator.wuandy.Book; // Declare any non-default types here with import statements interface IBookManger { /** * 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); List<Book>getBookList(); void addBook(in Book book); String getBookName(); }
运行你的aidl会报错,log显示找不到Book的定义,没错现在你的Book在aidl包下,编译时不会去它下面找类,此时你需要做以下工作,在build.gradle文件中加入以下代码。。
sourceSets{ main{ java.srcDirs = ['src/main/java', 'src/main/aidl'] } }
编译成功之后会出现
ALDL文件支持的格式那些数据类型呢?如下所示
基本数据类型
String和CharSequence
list:只支持ArrayList,里面的每个元素都必须能够被ALDL支持
Map:只支持HashMap,里面的每个元素都必须被ALDL支持,包括key和value
Parcelable:所有实现了Parcelable的对象
ALDL:所有ALDL接口本身也可以在ALDL文件中使用
注意
1.ALDL中除了基本数据类型,其他类型的参数必须表上方向:in 、out、inout,in表示输入型参数,out表示输出型参数,inout表示输入输出型参数
2. ALDL接口中只支持方法,不支持声明静态变量,
3.为了方便ALDL开发,建议将所有和ALDL相关的类和文件全部放入同一个包中,这样我们可以直接将整个包复制到客户端工程中,ALDL包的结构在客户端和服务端保持一致,否则会错。因为客户端要反序列化服务端中和ALDL接口相关的所有类,如果类的完整路径不对就无法成功反序列化。
4.远程服务端Service的实现
package com.example.administrator.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.support.annotation.Nullable; import com.example.administrator.wuandy.Book; import com.example.administrator.wuandy.IBookManger; import com.orhanobut.logger.Logger; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2018/2/8. */ public class MyService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return new MyBinder(); } class MyBinder extends IBookManger.Stub{ private List<Book> books=new ArrayList<>(); @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public List<Book> getBookList() throws RemoteException { Book book=new Book(1,"ANDROID"); books.add(book); Book book1=new Book(2,"IOS"); books.add(book1); Logger.d("MyBinder:集合_getBookList()"+books.size()); return books; } @Override public void addBook(Book book) throws RemoteException { books.add(book); Logger.d("MyBinder:集合_addBook()"+books.size()); } @Override public String getBookName() throws RemoteException { return "Java"; } } }
Service的注册
<service android:name="com.example.administrator.service.MyService" android:exported="true"> <intent-filter> <action android:name="com.Andy.ALDL"></action> </intent-filter> </service>
5.客户端的实现
package com.example.administrator.wuandy; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private IBookManger iBookManger; private Button start; private TextView content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); start=findViewById(R.id.start); content=findViewById(R.id.content); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(); intent.setAction("com.Andy.ALDL"); intent.setPackage("com.example.administrator.wuandy"); bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iBookManger=IBookManger.Stub.asInterface(service); Toast.makeText(MainActivity.this,"远程服务连接上了",Toast.LENGTH_SHORT).show(); } @Override public void onServiceDisconnected(ComponentName name) { } },BIND_AUTO_CREATE); } }); content.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { content.setText(iBookManger.getBookList().toString()); } catch (RemoteException e) { e.printStackTrace(); } } }); } @Override protected void onDestroy() { //注意要解绑 super.onDestroy(); } }
最后贴上运行之后的效果
相关文章推荐
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解 .
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android 四大组件之(2)Service实现原理以及AIDL语言的使用详解
- android aidl 使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android中RemoteService的使用详解(Aidl、IPC机制)