Android进程间通信AIDL基本使用(附源码)
2013-10-14 10:58
399 查看
什么是AIDL?
AIDL:Android Interface Definition Language,即Android接口定义语言。
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服务端步骤
1,在Eclipse
Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同
在这个文件中只定义了一个接口
package huahua.myaidlserver;
interface Ihuahua {
String greet(String someone);
}
2,如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)
上图中R.java上的那个Ihuahua.java就是系统自动生成的,这个文件不用管它,到时候在客户端需要用到
3,建立一个服务类AIDLServer,并实现由aidl文件生成的Java接口
Stub是存根的意思,在服务端创建Ihuahua.Stub对象,并且真正实现了Ihuahua.aidl接口中的方法.
4,在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值,这里我把原有默认启动的activity替换成了Service
<service
android:name="huahua.myaidlserver.AIDLService"
android:label="@string/app_name" >
<intent-filter>
<action android:name="huahuadashen.AIDLService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
好了,这个服务端的程序就写完了,就只提供了一个接口而已
需要注意的是,这个服务端程序是一个后台程序,没有界面显示!
下面是客户端的实现
新建一个Android应用程序MyAIDLClient,然后把MyAIDLServer程序中gen/huahua目录中的myaidlserver文件夹拷贝到新程序中的src/huahua目录下(huahua这个包名可以任意修改)
拷贝过去以后,只用保留Ihuahua.java系统自动生成的这个java文件,其他的都可以删掉
接着就可以编写主Activity代码了
就实现了3个功能
第1个按钮是绑定服务端,intent中的参数"huahuadashen.AIDLService"要和服务端AndroidManifest.xml中声明的行为<action
android:name="huahuadashen.AIDLService" />一致
第2个按钮取消绑定
绑定成功后,第3个按钮就可以用Ihuahua的对象来调用相应的接口了
可以看到在客户端程序中并不需要用到扩展名为aidl的文件,而且对于接口中的具体功能实现也看不到,
这个服务端程序跟C++中的动态库程序是不是有点相似呢,都是提供封装的接口给其他程序调用
下面是源代码地址
AIDL源码下载
AIDL:Android Interface Definition Language,即Android接口定义语言。
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服务端步骤
1,在Eclipse
Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同
在这个文件中只定义了一个接口
package huahua.myaidlserver;
interface Ihuahua {
String greet(String someone);
}
2,如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)
上图中R.java上的那个Ihuahua.java就是系统自动生成的,这个文件不用管它,到时候在客户端需要用到
3,建立一个服务类AIDLServer,并实现由aidl文件生成的Java接口
package huahua.myaidlserver; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class AIDLService extends Service { private static final String TAG = "huahua.AIDLService"; Ihuahua.Stub stub = new Ihuahua.Stub() { @Override public String greet(String someone) throws RemoteException { Log.i(TAG, "greet() called"); return "Hello " + someone+ "!"; } }; @Override public void onDestroy() { Log.i(TAG, "onDestroy() called"); super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "onUnbind() called"); return true; } @Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind() called"); return stub; } }
Stub是存根的意思,在服务端创建Ihuahua.Stub对象,并且真正实现了Ihuahua.aidl接口中的方法.
4,在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值,这里我把原有默认启动的activity替换成了Service
<service
android:name="huahua.myaidlserver.AIDLService"
android:label="@string/app_name" >
<intent-filter>
<action android:name="huahuadashen.AIDLService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
好了,这个服务端的程序就写完了,就只提供了一个接口而已
需要注意的是,这个服务端程序是一个后台程序,没有界面显示!
下面是客户端的实现
新建一个Android应用程序MyAIDLClient,然后把MyAIDLServer程序中gen/huahua目录中的myaidlserver文件夹拷贝到新程序中的src/huahua目录下(huahua这个包名可以任意修改)
拷贝过去以后,只用保留Ihuahua.java系统自动生成的这个java文件,其他的都可以删掉
接着就可以编写主Activity代码了
package huahua.myaidlclient; import huahua.myaidlserver.Ihuahua; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.util.Log; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private Button btn1; private Button btn2; private Button btn3; private Ihuahua ihuahuadashen; private ServiceConnection SC = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.i("ServiceConnection", "onServiceDisconnected() called"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("ServiceConnection", "onServiceConnected() called"); ihuahuadashen = Ihuahua.Stub.asInterface(service); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1 = (Button)findViewById(R.id.btn1); btn1.setOnClickListener(new BtnClick()); btn2 = (Button)findViewById(R.id.btn2); btn2.setOnClickListener(new BtnClick()); btn3 = (Button)findViewById(R.id.btn3); btn3.setOnClickListener(new BtnClick()); btn1.setEnabled(true); btn2.setEnabled(false); btn3.setEnabled(false); } private class BtnClick implements View.OnClickListener{ @Override public void onClick(View v) { if(v.getId() == R.id.btn1) { Intent intent = new Intent("huahuadashen.AIDLService"); bindService(intent, SC, Context.BIND_AUTO_CREATE); btn1.setEnabled(false); btn2.setEnabled(true); btn3.setEnabled(true); } else if(v.getId() == R.id.btn2) { unbindService(SC); btn1.setEnabled(true); btn2.setEnabled(false); btn3.setEnabled(false); } else if(v.getId() == R.id.btn3) { try { String str = ihuahuadashen.greet("everyone"); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { Toast.makeText(MainActivity.this, "异常", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
就实现了3个功能
第1个按钮是绑定服务端,intent中的参数"huahuadashen.AIDLService"要和服务端AndroidManifest.xml中声明的行为<action
android:name="huahuadashen.AIDLService" />一致
第2个按钮取消绑定
绑定成功后,第3个按钮就可以用Ihuahua的对象来调用相应的接口了
可以看到在客户端程序中并不需要用到扩展名为aidl的文件,而且对于接口中的具体功能实现也看不到,
这个服务端程序跟C++中的动态库程序是不是有点相似呢,都是提供封装的接口给其他程序调用
下面是源代码地址
AIDL源码下载
相关文章推荐
- android: 使用AIDL实现进程间通信(附示例源码下载)
- android: 使用AIDL实现进程间通信(附示例源码下载)
- Android 使用 AIDL 实现进程间通信,使用基本类型作为输入和输出参数
- android: 使用AIDL实现进程间通信(附示例源码下载)
- android进程间通信:使用AIDL
- Android-使用AIDL进程间通信
- android使用AIDL进程间通信遇到的一个小问题
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- 源码分析——从AIDL的使用开始理解Binder进程间通信的流程
- Android 图片加载框架Picasso基本使用和源码完全解析
- Android 的进程间通信 Binder——AIDL的入门使用(三)
- android进程间通信:使用AIDL
- Android AIDL(接口定义语言)简单理解和基本使用方法
- Android中Binder机制理解及AIDL使用基本步骤
- android进程间通信:使用AIDL
- Android使用AIDL实现进程间通信
- 学习笔记 Android 使用AIDL实现进程间通信
- android进程间通信:使用AIDL .
- android进程间通信:使用AIDL