Android初级教程进程间的通信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>
终于完成,本篇写了好久才完成~~~~(>_<)~~~~赶快留下您的而脚印吧!
Android初级教程进程间的通信AIDL的更多相关文章
- Android进程间的通信之AIDL
Android服务被设计用来执行很多操作,比如说,可以执行运行时间长的耗时操作,比较耗时的网络操作,甚至是在一个单独进程中的永不会结束的操作.实现这些操作之一是通过Android接口定义语言(AIDL ...
- 从AIDL开始谈Android进程间Binder通信机制
转自: http://tech.cnnetsec.com/585.html 本文首先概述了Android的进程间通信的Binder机制,然后结合一个AIDL的例子,对Binder机制进行了解析. 概述 ...
- Android 使用AIDL实现进程间的通信
在Android中,如果我们需要在不同进程间实现通信,就需要用到AIDL技术去完成. AIDL(android Interface Definition Language)是一种接口定义语言,编译器通 ...
- Android进程间的通信之Messenger
Android进程间的通信方式可以通过以下两种方式完成: Android接口定义语言(AIDL) 使用Messenger绑定服务 本文我们将学习使用Messenger绑定服务的方式进行进程间的通信. ...
- android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...
- Android进程间的通信
1.概述:由于android系统中应用程序之间不能共享内存.因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些.在android SDK中提供了4种用于跨进程通讯的方式.这4种方式正好对应于 ...
- Android查缺补漏(IPC篇)-- 进程间通讯之AIDL详解
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
- android 不同进程间的调用 AIDL 实现通讯服务
android 不同进程间的调用 AIDL 实现通讯服务 近期对aidl android 不同进程间的调用,不同运用间的调用做了一些尝试: 过程例如以下: 1:首先在要被调用的程序里写好 ...
- 服务 进程间通讯 IPC AIDL Parcelable 简介
1.IBinder和Binder是什么鬼? 我们来看看官方文档怎么说: 中文翻译: IBinder是远程对象的基本接口,是为了高性能而设计的轻量级远程调用机制的核心部分. 但他不仅用于远程调用,也用 ...
随机推荐
- 使用PL/SQL Developer连接远程DB(本机不安装Oracle客户端)
本文内容亲测可行环境: 服务端:centos6.7 ,oracle 11g r2 ,动态注册,监听端口号:1521 用户端:win7 ,没有安装ORACLE及其客户端 准备文件:plsql ...
- dev gridcontrol 无法编辑 解决方案
1.确认表格打开编辑 gridView1.OptionsBehavior.Editable = True 2.确认列打开编辑 gridView1.Columns("Name").O ...
- SecureFX连接Linux后文件夹中文乱码问题解决(转)
在使用SecureFX 连接Linux 时,发现文件夹显示乱码,一直尝试各种配置,现将方法整理一下!供大家参考! 首先在选项中设置字符编码为UTF-8 然后在全局选项中找到Securefx的配置文件 ...
- Exchange Server 2010升级到Exchange Server 2016
Hello各位小伙伴们,失踪人口回归啦~~~这次和大家分享Exchange Server 2010升级到Exchange Server 2016的方法.正式开始前先啰嗦几句,为什么我要写这篇文章呢?一 ...
- JAVA 中转义符的理解
生物信息中有时候会遇到JAVA写的程序,今天阅读源码的时候发现对于正则中的转义符不好理解,后来查资料后终于弄明白了,这里详细说明一下: 字符串的表示有三种方法:1.直接单字符,例如"A&qu ...
- MySQL 数学函数
MySQL 数学函数 所有的数学函数在发生错误的情况下,均返回 NULL. -元减.改变参数的符号 mysql> SELECT - 2; -> -2 注意,如果这个操作符被用于一个 BIG ...
- MYSQL 索引类型、什么情况下用不上索引、什么情况下不推荐使用索引
mysql explain的使用: http://blog.csdn.net/kaka1121/article/details/53394426 索引类型 在数据库表中,对字段建立索引可以大大提高查询 ...
- postgresql 登录查看表定义
su - postgres psql \connect database_name; \d table_name
- Python强大的可变参数传递机制
今天模拟定义map函数.写着写着就发现Python可变长度参数的机制真是灵活而强大. 假设有一个元组t,包含n个成员: t=(arg1,...,argn) 而一个函数f恰好能接受n个参数: f(arg ...
- jboss规则引擎KIE Drools 6.3.0 Final 教程(3)
在前2部教程中,介绍了如何在本地运行.drools文件以及使用stateless的方法访问远程repository上的规则. KIE Drools还提供了一种叫有状态-stateful的访问方式. 运 ...