Android IPC机制-AIDL详解
2017-03-24 22:36
393 查看
什么是AIDL?
官方解释:
AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似。 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。 在 Android 上,一个进程通常无法访问另一个进程的内存。 尽管如此,进程需要将其对象分解成操作系统能够识别的原语,并将对象编组成跨越边界的对象。 编写执行这一编组操作的代码是一项繁琐的工作,因此 Android 会使用 AIDL 来处理.通俗易懂:
就是Android接口定义语言, 就是一种语言.要学习的知识:
需要了解相关的Service知识, 而且还要了解通透, 所以我贴出我之前写的一篇文章: [四大组件] Service详解,你不知道的都在这里为什么会有AIDL?
其实我上面的官方解释也有说到为什么会有AIDL这门语言, 主要是为了实现 进程间的通信.也就是一个进程可以访问另一个进程的数据, 甚至调用一些方法.
定义AIDL接口
准备
AIDL语法
AIDL支持下列数据类型:Java中所有原语类型(如int,long,char,boolean等)
String、CharSequence、List、Map
定义服务接口时,需注意:
方法可带零个或多个参数,返回值或空值。
所有非原语参数都需要指示数据走向的方向标记。可以是in、out或inout(见以下示例)。原语默认为 in,不能是其他方向。
两种AIDL文件
定义parcelable对象定义方法接口
注: 所有非默认支持数据类型必须通过第一类AIDL文件定义才能被使用.
实例操作
数据类实现Parcelable接口
为了使一个进程能够访问到另一个进程的数据, 我们需要将类序列化, 然后再将数据传到服务端, 服务端反序列化操作, 从而获取到了数据.首先创建一个实体类, 并且实现Parcelable接口的一些方法, 代码如下:
public class Book implements Parcelable { private String name; private String author; public Book(String name) { this.name = name; } protected Book(Parcel i 4000 n) { name = in.readString(); author = in.readString(); } public static final Creator<Book> CREATOR = new Creator<Book>() { @Override public Book createFromParcel(Parcel in) { return new Book(in); } @Override public Book[] newArray(int size) { return new Book[size]; } }; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeString(author); } }
书写.aidl文件
如果你是使用Android studio的话, 可以像下图创建aidl文件:首先创建Book.aidl
//第一类AIDL文件 引入一个序列化对象Book供其他AIDL文件使用 package com.rcd.democomponents; parcelable Book;
然后是BookManager.aidl
//这个是第二类AIDL, 定义方法接口 package com.rcd.democomponents; //这里需要导入所需要使用的非默认支持数据类型的包 import com.rcd.democomponents.Book; interface BookManager { List<Book> getBook(); void addBook(in Book book); }
然后是Service的书写:
public class DemoService extends Service { private static final String TAG = "demoservice"; private List<Book> mBooks; private IBinder mBinder=new BookManager.Stub(){ @Override public List<Book> getBook() throws RemoteException { synchronized (this){ Log.d(TAG, "getBook: "); return new ArrayList<>(); } } @Override public void addBook(Book book) throws RemoteException { synchronized (this){ if(mBooks==null){ mBooks=new ArrayList<>(); } if(book==null){ book=new Book(); } if(!mBooks.contains(book)){ mBooks.add(book); } Log.d(TAG, "addBook: "+mBooks.toString()); } } }; @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); mBooks=new ArrayList<>(); Book book=new Book(); book.setName("那时候坚持不懈的我"); mBooks.add(book); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: "); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.d(TAG, "onDestroy: "); super.onDestroy(); } @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } }
就是实现BookManager.Stub中的两个AIDL已定义的方法来获取IBinder的实例, 然后在onBind方法返回这个mBinder.
最后是客户端的代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "MainActivity"; private Button mBtnStart, mBtnStop, mBtnBind, mBtnUnbind; private BookManager mBookManager; private List<Book> mBooks; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBookManager=BookManager.Stub.asInterface(service); if(mBookManager!=null){ try { mBooks=mBookManager.getBook(); } catch (RemoteException e) { e.printStackTrace(); } } } @Override public void onServiceDisconnected(ComponentName name) { Log.d(TAG, "onServiceDisconnected: "); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtnStart = (Button) findViewById(R.id.btn_start); mBtnStop = (Button) findViewById(R.id.btn_stop); mBtnBind = (Button) findViewById(R.id.btn_bind); mBtnUnbind = (Button) findViewById(R.id.btn_unbind); mBtnStart.setOnClickListener(this); mBtnStop.setOnClickListener(this); mBtnBind.setOnClickListener(this); mBtnUnbind.setOnClickListener(this); } @Override public void onClick(View v) { Intent intent = new Intent(this, DemoService.class); switch (v.getId()) { case R.id.btn_start: startService(intent); break; case R.id.btn_stop: stopService(intent); break; case R.id.btn_bind: bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); break; case R.id.btn_unbind: unbindService(mServiceConnection); break; default: break; } } //addBook_ aidl private void addBook(View view){ if(mBookManager!=null){ Book book=new Book(); book.setName("你好啊"); try { mBookManager.addBook(book); } catch (RemoteException e) { e.printStackTrace(); } } } }
这里实现了ServiceConnection的两个方法,并且使用BookManager.Stub.asInterface(service)获取到了BookManager的实例, 所以可以调用addBook和getBook的方法.
效果图
有关AIDL今天先介绍到这里, 有兴趣的朋友可以上官网去看详细的Demo教程.
相关文章推荐
- Android AIDL IPC机制详解
- Android中RemoteService的使用详解(Aidl、IPC机制)
- (转)Android IPC机制详解
- Android的IPC机制Binder的详解汇总
- Android进程间通信(IPC)的AIDL机制:Hello World示例
- Android IPC机制详解
- Android IPC 机制详解:IBinder
- Android IPC 机制详解:IBinder
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- Android IPC机制详解
- AIDL/IPC Android AIDL/IPC 进程通信机制——超详细讲解及用法案例剖析(播放器)
- Android的IPC机制Binder的详解(转发)
- Android的IPC机制Binder的详解(转发)
- Android AIDL IPC机制
- Android IPC机制 详解
- Android的IPC机制Binder的详解汇总
- Android的IPC机制Binder的详解汇总
- Android IPC机制详解
- Android IPC机制详解
- Android进阶:AIDL实现IPC使用详解