问题小结(20)--AIDL学习及使用
来源:互联网 发布:天地图数据规范 编辑:程序博客网 时间:2024/06/06 07:42
AIDL:是 Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言,通过它我们可以用来不同进程间的通信。
最初接触aidl的时候,只是敲了一下教材上的代码,没有静下来思考过,感觉挺复杂的,由于畏难情绪在作祟,且目前还没有需要用到aidl的项目,所以一直就没有好好的研究过。今天仔细的看了一下,简单的梳理了一下流程,感觉其实不难的,所以在这里,我会用自己的方式描述一下它的整个的工作流程(可能原理上不是这样的)。
一、服务端部分
首先我们要定义服务器端的aidl文件,在我们写好aidl文件时,然后 Android Eclipse 插件会自动帮你 根据这个 AIDL 文件生成 Java文件,在gen目录下,并且和其包名对应。
package com.duke.aidl;interface IService { String setValue(String value); String getValue(String value);}
当然客户端程序程序所用到的aidl文件和服务器端是一样的,并且双方aidl文件所在的包名也要相同。
aidl里面声明的方法也就是客户端程序能够调用的服务器端的方法。
然后就是在服务类中实现aidl文件里声明的方法
package com.duke.aidl;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class ServiceRunning extends Service{String mvValue="duke";public class ServiceRunningImpl extends IService.Stub{//实现方法就是通过继承aidl文件自动生成的java文件里的内部类实现的,我们不需要深究它是如何自动生成的,也不需要知道它里面有什么东西@Overridepublic String setValue(String value) throws RemoteException {// TODO Auto-generated method stubmvValue=value;return mvValue;}@Overridepublic String getValue(String value) throws RemoteException {// TODO Auto-generated method stubreturn value+":"+mvValue;}}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn new ServiceRunningImpl();}}
在这个服务类中大家可以看到我们实现了 onBind() 方法。从AIDL文件生成的 Stub类是抽象类并且它实现了 IService接口。在我们的服务实现中,有一个扩展了 Stub类得内部类,名为 ServiceRunningImpl。此类充当着远程服务实现,而且 onBind()方法会返回此类的实例。到此,我们有了一个有效的 ADIL服务,但是外部的客户端还无法连接到它。
最后呢要将服务向客户端公开,需要在AndroidManifest.xml文件中添加服务声明,而这一次我们需要一个Intent 过滤器来公开服务,如下:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.duke.aidl" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <service android:name=".ServiceRunning"> <intent-filter> <action android:name="com.duke.aidl.ServiceRunning"/> </intent-filter> </service> </application></manifest>
二、客户端程序
当客户端与服务通信时,它们之间必须有一个协议或契约(AIDL)。所以,使用服务的第一步是,获取服务的 AIDL文件并将其复制到客户端项目中。当将AIDL文件复制到客户端项目时,AIDL 编译器将创建一个接口定义文件,这个文件与我们在服务端定义的文件相同。这会向客户端公开所有的方法、参数并返回服务的类型。
首先新建一个客户端工程,当然了包名不能和服务器端相同。
其次根据服务器端的aidl文件所在的包名,新建一个相同的包,让后将服务器端的aidl文件复制到客户端工程新建的包下。
最后是获取服务的引用,以便调用服务器端实现的方法。对于远程服务,必须调用 bindService()方法,而不是 startService()方法。
package com.duke.aidl.client;import com.duke.aidl.IService;import android.app.Activity;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.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class AidlServiceClientActivity extends Activity { /** Called when the activity is first created. */private IService mService=null;private Button btn,btn1,btn2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(Button) findViewById(R.id.button); btn1=(Button) findViewById(R.id.button1); btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubbindService(new Intent("com.duke.aidl.ServiceRunning"), sercon, Context.BIND_AUTO_CREATE);}}); btn1.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubcallService();}}); btn2=(Button) findViewById(R.id.button2); btn2.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubunbindService(sercon);}}); } private ServiceConnection sercon=new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubmService=null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubmService=IService.Stub.asInterface(service);//callService();}};private void callService(){try { // String str=mService.setValue("value"); String val=mService.getValue("hello world"); Toast.makeText(this, "Value from service is " + val, Toast.LENGTH_LONG).show(); } catch (RemoteException e) { Log.e("MainActivity", e.getMessage(), e); } }}
对于AIDL 服务,需要提供ServiceConnection接口的实现。此接口定义了两个方法:一个供系统建立服务连接时调用,另一个在销毁服务连接时调用。
布局文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/tv" android:text="@string/hello" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/button" android:text="bindService" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/button1" android:text="callService" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/button2" android:text="unbindService" /></LinearLayout>
第一个按钮是绑定启动服务,第二个是调用一下方法来验证是否实现了和服务器端的通信,第三个是解绑服务。
为了避免大家把aidl文件放错位置,来2张我们程序结构的截图吧,一个是服务端得,一个是 客户端的。
服务器端:
客户端:
总结:服务器端的aidl文件声明方法,通过服务实现这些方法
客户端的aidl文件是告诉客户端它所能调用到的服务器端的哪些方法,然后通过绑定启动服务,通过ServiceConnection和服务器建立连接通信,进而调用服务器端实现的方法体。
- 问题小结(20)--AIDL学习及使用
- AIDL 学习小结
- AIDL使用小结
- android AIDL学习问题
- Android进程间通讯AIDL使用及问题详解(雷惊风)
- Android 5.0及更高系统使用AIDL的问题
- AIDL 使用学习
- 分页问题学习及一些小结
- aidl小结
- AIDL小结
- AIDL使用学习(一):基础使用学习
- 学习AIDL遇到的问题
- Android学习 - Aidl的使用
- Android 学习 AIDL 的使用
- Android:学习AIDL使用详解
- AIDL使用学习(二):跨进程回调以及RemoteCallbackList
- AIDL使用学习(三):源码深入分析
- AIDL的简单使用,涵盖5.0之后系统及魅族手机调用问题的解决
- 关于String和inputStream的转换
- ios第三方库---下拉刷新
- 封装一类圆形对象Circle,并完善其功能
- 编程之美区间覆盖
- 算法研究(二) bitmap在排序中的妙用
- 问题小结(20)--AIDL学习及使用
- ubutnu12.04上fcitx安装
- GDB/ARMulator 使用方法
- iframe高度自适应
- 黑马程序员——自学笔记12(图形化界面编程1—各种组件及创建)
- 利用qemu-img创建系统镜像补丁,解决系统升级的方法
- JSTL 标签库详细介绍资料 .
- 标准输入输出
- 静静的在心里承受所有的伤痛和不快乐