AIDL
在介绍跨程序进程间通信AIDL前,先看一下本程序activity与某个服务是怎么绑定在一起进行交互的。
需求:服务有两个方法。分别是播放音乐与停止播放音乐。该程序的活动要访问这两个方法,在activity中控制服务的这两个方法,通过点击按钮的方式实现停止与播放音乐。
对同一个程序服务与活动交互的方式,先给出一张图片:
给出代码(案例为模拟音乐播放器):
一、定义一个服务类MusicService:
package com.ydl.music; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; public class MusicService extends Service { @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return new MusicController();// 把中间人对象返回给绑定服务方法。 } class MusicController extends Binder implements Musicinterface {// 实现接口是为了让绑定的而活动仅仅调用相应的方法 // 比如本服务还有一个打麻将方法,不想被活动调用。则抽取接口指定访问的方法。 // 中间人里面有两个方法可以访问到本服务中的停止和播放方法 public void play() { MusicService.this.play(); } public void pause() { MusicService.this.pause(); } public void daMaJiang() { system.out.println("陪领导打麻将"); } } // 本程序有两个方法 public void play() { System.out.println("播放音乐"); } public void pause() { System.out.println("停止播放音乐"); } }
二、抽取interface接口:
package com.ydl.music; public interface MusicInterface { void play(); void pause(); }
三、主活动界面:
package com.ydl.music; import android.os.Bundle; import android.os.IBinder; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { MusicInterface mi; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, MusicService.class); //注意:这里需要混合调用 /** * 混合调用:既要调用startservice有需要bindService。因为只调用bindService服务与活动绑定在一起的,当用户返回键使得activity进入后台 * 此时服务也会进入后台模式,很容易被杀死进程。从而没法播放音乐。 */ startService(intent); bindService(intent, new MusicServiceConn(), BIND_AUTO_CREATE);//第二个参数是一个服务连接对象,活动与服务的关联起着很重要的作用 } class MusicServiceConn implements ServiceConnection{//服务连接方法 @Override//与服务绑定的时候调用 public void onServiceConnected(ComponentName name, IBinder service) { mi = (MusicInterface) service; } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } } public void start(View v) { mi.play(); } public void stop(View v) { mi.pause(); } }
四、去清单文件配置我们自定义的服务
<service android:name="com.ydl.music.MusicService"></service>
运行后可以实现活动调用服务的方法,实现音乐播放器的播放与暂停,同时及时在后台时,服务进程也很难被杀掉。(当然这里播放音乐的逻辑仅仅是打印一行log)
好了。有了上边的基础,就来开始探讨AIDL通信了。
还是给出一张图。大致看一下意思:
场景:两个项目,01和02.其中01项目是一个服务类,有一些方法;02项目是一个activity类。02项目想去使用01项目服务中的方法,就需要跨进程进行通信。
使用传统的bindservice()方法已经没办法,因此使用AIDL技术——
AIDL技术使用步骤:(注意:此时必须隐式方式绑定服务)
- Android interface definition language
- 进程间通信
- 把远程服务的方法抽取成一个单独的接口Java文件
- 把接口java文件的后缀名改成aidl
- 在自动生成gen文件中的PublicBusiness.java文件中,有一个静态抽象类Stub,它已经继承了Binder类,实现了publicBusiness接口,这个抽象类就是新的中间人
- 把aidl文件复制粘贴到06项目,粘贴的时候注意,aidl文件所在的包名必须跟05项目中aidl所在的包名一致。此时06项目中也拥有了与05一模一样的Stub类
- 在06项目中,强转中间人对象时,直接使用Stub.asInterface()。它直接做了强制转
一、定义远程服务程序:(这里模拟支付宝支付功能,远程服务定义名称为PayService,中间人类定义为小胖子PayPangzhi)
1、把上边接口的文件修改后缀名为aidl
改远程服务端的代码:
package com.ydl.remoteservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import com.ydl.remoteservice.PayInterface.Stub; public class PayService extends Service { @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return new PayPangZhi(); } class PayPangZhi extends Stub {//胖纸作为中间人,注意继承的是Stub类 @Override public void pay() throws RemoteException { PayService.this.pay(); } } public void pay() {//虚假的支付功能,以log方式模拟 System.out.println("加测运行环境"); System.out.println("加密用户名和密码"); System.out.println("建立连接"); System.out.println("完成支付"); } }
活动中的方法:
package com.example.startpayservice; import com.ydl.remoteservice.PayInterface; import com.ydl.remoteservice.PayInterface.Stub; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.View; public class MainActivity extends Activity { PayInterface pi; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent();//隐式绑定服务 intent.setAction("com.ydl.pangzhi"); bindService(intent, new ServiceConnection() {//第二个链接对象采用匿名内部类方式 @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { pi = Stub.asInterface(service);//这里自动做了强制类型转换 } }, BIND_AUTO_CREATE); } public void click(View v){ try { pi.pay(); } catch (RemoteException e) {//请求远程服务支付异常 // TODO Auto-generated catch block e.printStackTrace(); } } }
清单文件中配置方式改为隐式:
<service android:name="com.ydl.remoteservice.PayService"> <intent-filter > <action android:name="com.ydl.pangzhi"/> </intent-filter> </service>
AIDL的更多相关文章
- Android探索之AIDL实现进程间通信
前言: 前面总结了程序间共享数据,可以使用ContentProvider也可以使用SharedPreference,那么进程间怎么共享内存呢?Android系统中的进程之间不能共享内存,因此,需要提供 ...
- 了解AIDL
1.什么是AIDL? Android Interface Definition Lauguage(android接口描述语言)是一个IDL语言. 2.AIDL的作用? 背景:在android平台 中, ...
- Android开发aidl使用中linkToDeath和unlinkToDeath的使用
1.Binder死亡代理 这一节首先将介绍Binder类中比较重要的两个方法linkToDeath和unlinkToDeath.我们知道Binder是运行在服务进程,若服务端进程因为某种原因“ ...
- android不需要Socket的跨进程推送消息AIDL!
上篇介绍了跨进程实时通讯http://www.cnblogs.com/xiaoxiaing/p/5818161.html 但是他有个缺点就是服务端无法推送消息给客户端,今天这篇文章主要说的就是服务器推 ...
- Android中利用AIDL机制调用远程服务
服务端: //CalculateInterface.aidl package com.itheima.aidl.calculate; interface CalculateInterface { do ...
- Android中AIDL的理解与使用(二)——跨应用绑定Service并通信
跨应用绑定Service并通信: 1.(StartServiceFromAnotherApp)AIDL文件中新增接口: void setData(String data); AppService文件中 ...
- Android中AIDL的理解与使用(一)——跨应用启动/绑定Service
AIDL(Android Interface Definition Language)--安卓接口定义语言 一.startService/stopService 1.同一个应用程序启动Service: ...
- 安卓中AIDL的使用方法快速入门
1.AIDL是什么? AIDL全称是Android Interface Definition Language,即安卓接口定义语言. 2.AIDL是用来做什么的?(为什么要有AIDL) AIDL是用来 ...
- make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl] 错误 1,make: *** [out/host/linux-x86/obj/lib/libESR_Portable.so] 错误 1
错误3: g++: g++: selected multilib '32' not installed selected multilib '32' not installed make: *** [ ...
- 使用AIDL调用远程服务设置系统时间
在实际工作中,经常遇到客户需要用代码设置系统时间的需求,但是Android非系统应用是无法设置系统时间的.于是,我设计了一个使用系统签名的时间设置服务,客户通过bind调用服务里的方法就能达到设置时间 ...
随机推荐
- linux shell脚本通过参数名传递参数值
平常在写shell脚本都是用$1,$2....这种方式来接收参数,然而这种接收参数的方式不但容易忘记且不易于理解和维护.Linux常用的命令都可指定参数名和参数值,然而我们怎样才能给自己的shell脚 ...
- std::map
1.例: map<int,string> m_mapTest; m_mapTest.insert(make_pair(1,"kong")); m_mapTest.ins ...
- 在java项目中使用AES256 CBC加密
首先要注意一点,默认的JDK是不支持256位加密的,需要到Oracle官网下载加密增强文件(Java Cryptography Extension (JCE) Unlimited Strength J ...
- 括号配对问题_栈<stack>
问题 A: 括号配对问题 时间限制: 3 Sec 内存限制: 128 MB提交: 3 解决: 2[提交][状态][讨论版] 题目描述 现在,有一行括号序列,请你检查这行括号是否配对. 输入 第一行 ...
- codeforces 591A. Wizards' Duel 解题报告
题目链接:http://codeforces.com/problemset/problem/591/A 题目意思:其实看下面这幅图就知道题意了,就是Harry 和 He-Who-Must-Not-Be ...
- vs2013显示行号
随便打开一个项目,可以看到代码框内并没有显示行号 选择“工具”-“选项”,打开后界面如下 选择文本编辑器,找到下图中的“行号”并勾选 行号可以显示了 5 这样我们就完成了任务
- tomcat URL乱码问题
用get传参时,显示乱码 在tomcat里的server.xml中添加一下即可. <Connector port="8080" protocol="HTTP/1.1 ...
- MVP设计模式的实现
MVP:界面与业务逻辑分离在Winform中的应用 MVP,Model-View-Presenter的缩写. 在MSDN上,下载了一个示例,http://www.microsoft.com/china ...
- supersr--KVO/KVC
KVO内部实现原理 1.KVO是基于runtime机制实现的. 2.当某个类的对象第一次被观察是,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的set方法.派生类 ...
- [Android Pro] DES加密 version1
reference to : http://blog.csdn.net/wfung_kwok/article/details/7766029 加密和解密要用同一個key AES: import jav ...