标签:
在介绍跨程序进程间通信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("停止播放音乐");
}
}
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>
好了。有了上边的基础,就来开始探讨AIDL通信了。
还是给出一张图。大致看一下意思:
场景:两个项目,01和02.其中01项目是一个服务类,有一些方法;02项目是一个activity类。02项目想去使用01项目服务中的方法,就需要跨进程进行通信。
使用传统的bindservice()方法已经没办法,因此使用AIDL技术——
AIDL技术使用步骤:(注意:此时必须隐式方式绑定服务)
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>
标签:
原文地址:http://blog.csdn.net/qq_32059827/article/details/51702218