转载声明:原文转自:http://www.cnblogs.com/xiezie/p/5658372.html

什么是AIDL

  Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
  为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
 

建立AIDL服务的步骤

建立AIDL服务要比建立普通的服务复杂一些,具体步骤如下:
(1)在Eclipse Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同。
(2)如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)。
(3)建立一个服务类(Service的子类)。
(4)实现由aidl文件生成的Java接口。
(5)在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。
   另外,要设置service的process属性为":remote"
实现AIDL接口的说明:
(1)AIDL接口只支持方法,不能声明静态成员;
(2)不会有返回给调用方的异常。
 

AIDL实例

服务器端

1.建立JavaBean--Model    book.java 继承 Parceable 实现序列化。

package testaidl.x.com.testaidl.aidl;

import android.os.Parcel;
import android.os.Parcelable; /**
* Created by Administrator on 2016/7/10.
*/
public class Book implements Parcelable { public int id;
public String name; public Book(int id, String name) {
this.id = id;
this.name = name;
} private Book(Parcel in) {
id = in.readInt();
name = in.readString();
} @Override
public int describeContents() {
return 0;
} @Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(id);
out.writeString(name);
} 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];
}
};
}

2.(Android Studio) 在src/main/下 建立 aidl 包(与java同级),在aidl下建立JavaBean相同目录的包

  建立JavaBean相同名称的.aidl文件 --> Book.aidl

  建立服务接口的.aidl文件 --> IBookManager.aidl  (必须  import testaidl.x.com.testaidl.aidl.Book;)

// IBook.aidl
package testaidl.x.com.testaidl.aidl; parcelable Book;
// IBookManager.aidl
package testaidl.x.com.testaidl.aidl; import testaidl.x.com.testaidl.aidl.Book; interface IBookManager { List<Book> getAllBook();
void addBook(in Book book); }

目录:

3.此时,进行编译 如果aidl文件的内容是正确的,IDE会自动生成在根目录下一个Java接口文件(*.java)。-->IBookManager.java

4.建立一个服务类(Service的子类)。-->RemoteService.java

package testaidl.x.com.testaidl.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException; import java.util.LinkedList;
import java.util.List; /**
* Created by Administrator on 2016/7/10.
*/
public class RemoteService extends Service { private List<Book> mBooks = new LinkedList<>(); @Override
public IBinder onBind(Intent intent) {
return mBinder;
} private final IBookManager.Stub mBinder = new IBookManager.Stub() {
@Override
public List<Book> getAllBook() throws RemoteException {
return mBooks;
} @Override
public void addBook(Book book) throws RemoteException {
if(book!=null){
mBooks.add(book);
}
}
};
}

5.在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。

  另外,要设置service的process属性为":remote"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="testaidl.x.com.testaidl" > <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=".aidl.RemoteService"
android:process=":remote">
<intent-filter>
<action android:name="testaidl.x.com.testaidl.aidl.RemoteService"/>
</intent-filter>
</service>
</application> </manifest>

客户端

1.(Android Studio) 在src/main/下 建立 aidl 包和(与服务端包名一致)JavaBean相同目录的包,并将JavaBean和 JavaBean、服务的AIDL文件全部复制(与服务端包名一致)

2.建立Activity界面-->MainActivity.java

package testaidl.x.com.testaidl.aidl;

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.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast; import java.util.ArrayList;
import java.util.List; import testaidl.x.com.testaidl.R; public class MainActivity extends AppCompatActivity { private ListView mListView;
private EditText mEditText;
private List<Book> mBooks = new ArrayList<>(); private IBookManager mService;
private static boolean mIsRemoteBound = false; private ServiceConnection conn = new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IBookManager.Stub.asInterface(service);
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.list);
mEditText = (EditText) findViewById(R.id.input_name);
if(mIsRemoteBound){
unbindService(conn);
}else{
Intent intent=new Intent("testaidl.x.com.testaidl.aidl.RemoteService");//这里的action应与服务端的Service的<action>名称相同
bindService(intent, conn, BIND_AUTO_CREATE);
}
mIsRemoteBound = !mIsRemoteBound;
} static int id = 0; public void addBook(View v) {
String name = mEditText.getText().toString();
if(name.equals("")){
Toast.makeText(getApplicationContext(),"名字不能为空",Toast.LENGTH_SHORT).show();
}else{
Book book = new Book(id++,name);
try {
mService.addBook(book);
Toast.makeText(getApplicationContext(),"添加书籍成功",Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"添加书籍失败:" + e.toString(),Toast.LENGTH_SHORT).show();
}
} } public void getBooks(View v){
try {
mBooks = mService.getAllBook();
} catch (RemoteException e) {
e.printStackTrace();
}
mListView.setAdapter(new MBookAdapter(getApplicationContext(),mBooks,R.layout.item_book));
} class MBookAdapter extends CommonAdapter<Book> {
public MBookAdapter(Context context, List<Book> mDatas, int itemLayoutId) {
super(context, mDatas, itemLayoutId);
} @Override
public void convert(ViewHolder helper, Book item, int position) {
helper.setText(R.id.book_id,item.id + "");
helper.setText(R.id.book_name,item.name + "");
}
}
}

AIDL实例的更多相关文章

  1. Android AIDL实例解析

    AIDL这项技术在我们的开发中一般来说并不是很常用,虽然自己也使用新浪微博的SSO登录,其原理就是使用AIDL,但是自己一直没有动手完整的写过AIDL的例子,所以就有了这篇简单的文章. AIDL(An ...

  2. Android AIDL 实例

    为使应用程序之间能够彼此通信,Android提供了IPC (Inter Process Communication,进程间通信)的一种独特实现: AIDL (Android Interface Def ...

  3. Android探索之旅 | AIDL原理和实例讲解

    轉載自http://www.jianshu.com/p/ef86f682a8f9 -- 作者 谢恩铭 转载请注明出处 前言 为使应用程序之间能够彼此通信,Android提供了IPC (Inter Pr ...

  4. android AIDL 语言用法

    跨进程通信可以用AIDL语言 这里讲述下如何使用AIDL语言进行跨进程通信 文章参考 <设计模式>一书 demo结构参考 主要的文件类有:IBankAidl.aidl java文件:Aid ...

  5. Binder or AIDL的最简单实践

    1.前言: 在Android开发中多进程的合理使用+进程间通信的IPC是一个比较难的点.特别是Android特有的Binder机制,非常复杂,对于应用层开发的初级开发工程师强求深入理解Binder机制 ...

  6. Android 进阶7:进程通信之 AIDL 的使用

    读完本文你将了解: AIDL 是什么 AIDL 支持的数据类型 AIDL 如何编写 AIDL 实例 创建 AIDL 编写服务端代码 编写客户端代码 运行结果 总结 代码地址 Thanks 记得 201 ...

  7. 1.4 Service

    用于在后台完成用户指定的操作,为其他组件提供后台服务或监控其他组件的运行状态. 开发人员需要在应用程序配置文件中声明全部的service,使用<service></service&g ...

  8. android ipc通信机制之二序列化接口和Binder

    IPC的一些基本概念,Serializable接口,Parcelable接口,以及Binder.此核心为最后的IBookManager.java类!!! Serializable接口,Parcelab ...

  9. android service总结

    1.通过startservice方法启动一个服务.service不能自己启动自己.若在一个服务中启动一个activity则,必须是申明一个全新的activity任务TASK.通过startservic ...

随机推荐

  1. LA 4731

    dp[i][j]意思是前i个分成j组最小的花费 #include<cstdio> #include<algorithm> #include<cstring> #in ...

  2. DIY Ruby CPU 分析——Part III

    [编者按]作者 Emil Soman,Rubyist,除此之外竟然同时也是艺术家,吉他手,Garden City RubyConf 组织者.本文是 DIY Ruby CPU Profiling 的第二 ...

  3. 16进制字符串转数字(C/C++,VB/VB.net,C#)

    这个问题看是很简单,但是在不同语言中实现的方式却千差万别,如果不知道方法,还真是麻烦,我就是在C#中遇到该问题,让我费了很大的周折,才在msdn查到. 一.16进制字符串转数字      1.C/C+ ...

  4. Java将整个文件夹里的文本中的字符串替换成另外一个字符串(可用于项目复制,变成另一个项目)

    import org.junit.Test; import java.io.*; /** * User: HYY * Date: 13-8-18 * Time: 下午8:11 * To change ...

  5. CodeChef November Challenge 2014

    重点回忆下我觉得比较有意义的题目吧.水题就只贴代码了. Distinct Characters Subsequence 水. 代码: #include <cstdio> #include ...

  6. 【零基础学习iOS开发】【02-C语言】09-流程控制

    前言 1.默认的运行流程 默认情况下,程序的运行流程是这样的:运行程序后,系统会按书写顺序执行程序中的每一行代码.比如下面的程序 1 #include <stdio.h> 2 3 int ...

  7. WinAPI——钩子函数大全2

    CallNextHookEx 函数功能:该函数发送挂钩信息给当前挂钩链中的下一个挂钩处理过程,一个挂钩处理过程可在对该挂钩信息进行处理之前或之后调用本函数. 函数原形:LRESULT CallNext ...

  8. 【HDOJ】4297 One and One Story

    综合性很强的题目.存在环,可以用tarjan处理,然后需要求LCA.并查集+RMQ可以搞.非常不错的题目. /* 4297 */ #include <iostream> #include ...

  9. MAX-HEAPIFY(2/3n的疑惑)

    Q: In CLRS, third Edition, on page 155, it is given that in MAX-HEAPIFY, The children’s subtrees eac ...

  10. tap,touch,touchstart,事件与click事件的区别

    根据源码所见, 移动端为了将将单击事件更加灵敏,所以现在的JQM,ST...框架都将JS单击事件封装成tap,或者touch或者touchstart事件, 其实现本质是将click触发多次,以打成移动 ...