在android平台中,一个进程通常不能访问其他进程中的内存区域的。但是,我们可以使用IDL语言来把对象伪装成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。
如果想在应用程序中调用其他进程中的Service,则需要用到AIDL,AIDL(android接口描述语言)是一种IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如:在一个Activity中)访问另一个进程中(例如:一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。
使用AIDL的方法如下:
1.首先生成一个IMusicService.aidl的服务接口,Android会自动生成一个 Stub类,这个类继承了BInder类,同时继承了IMusicService这个接口,还可以看到其中包含了一个Proxy代理类,以实现远程代理。(aidl和Stub类如下所示)
- /**
- * IMusicService.aidl
- * com.androidtest.service.mediaplayer
- *
- * Function: TODO
- *
- * ver date author
- * ──────────────────────────────────
- * 2011-5-19 Leon
- *
- * Copyright (c) 2011, TNT All Rights Reserved.
- */
- package com.androidtest.service.mediaplayer;
- /**
- * ClassName:IMusicService
- * Function: TODO ADD FUNCTION
- * Reason: TODO ADD REASON
- *
- * @author Leon
- * @version
- * @since Ver 1.1
- * @Date 2011-5-19
- */
- interface IMusicService{
- void play();
- void pause();
- void stop();
- }
- /*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: D:\\Backup\\�ҵ��ĵ�\\Dropbox\\investment\\A8\\workspace\\androidtest\\src\\com\\androidtest\\service\\mediaplayer\\IMusicService.aidl
- */
- package com.androidtest.service.mediaplayer;
- /**
- * ClassName:IMusicService Function: TODO ADD FUNCTION Reason: TODO ADD REASON
- *
- * @author Leon
- * @version
- * @since Ver 1.1
- * @Date 2011-5-19
- */
- public interface IMusicService extends android.os.IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements
- com.androidtest.service.mediaplayer.IMusicService {
- private static final java.lang.String DESCRIPTOR = "com.androidtest.service.mediaplayer.IMusicService";
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an
- * com.androidtest.service.mediaplayer.IMusicService interface,
- * generating a proxy if needed.
- */
- public static com.androidtest.service.mediaplayer.IMusicService asInterface(
- android.os.IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- android.os.IInterface iin = (android.os.IInterface) obj
- .queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof com.androidtest.service.mediaplayer.IMusicService))) {
- return ((com.androidtest.service.mediaplayer.IMusicService) iin);
- }
- return new com.androidtest.service.mediaplayer.IMusicService.Stub.Proxy(
- obj);
- }
- public android.os.IBinder asBinder() {
- return this;
- }
- @Override
- public boolean onTransact(int code, android.os.Parcel data,
- android.os.Parcel reply, int flags)
- throws android.os.RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_play: {
- data.enforceInterface(DESCRIPTOR);
- this.play();
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_pause: {
- data.enforceInterface(DESCRIPTOR);
- this.pause();
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_stop: {
- data.enforceInterface(DESCRIPTOR);
- this.stop();
- reply.writeNoException();
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements
- com.androidtest.service.mediaplayer.IMusicService {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote) {
- mRemote = remote;
- }
- public android.os.IBinder asBinder() {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
- public void play() throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_play, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- public void pause() throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_pause, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- public void stop() throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_stop, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- }
- static final int TRANSACTION_play = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
- static final int TRANSACTION_pause = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
- static final int TRANSACTION_stop = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
- }
- public void play() throws android.os.RemoteException;
- public void pause() throws android.os.RemoteException;
- public void stop() throws android.os.RemoteException;
- }
2. 在MyRemoteBinder需要继承这个Stub类,对播放器的控制写在这个Binder类中
?[Copy to clipboard]
Download zuiniuwang.java
- /**
- * MyRemoteBinder.java
- * com.androidtest.service.mediaplayer
- *
- * Function: TODO
- *
- * ver date author
- * ──────────────────────────────────
- * 2011-5-19 Leon
- *
- * Copyright (c) 2011, TNT All Rights Reserved.
- */
- package com.androidtest.service.mediaplayer;
- import android.media.MediaPlayer;
- import android.os.Binder;
- import android.os.RemoteException;
- /**
- * ClassName:MyRemoteBinder
- * Function: TODO ADD FUNCTION
- * Reason: TODO ADD REASON
- *
- * @author Leon
- * @version
- * @since Ver 1.1
- * @Date 2011-5-19
- */
- public class MyRemoteBinder extends IMusicService.Stub{
- public MyRemoteBinder(MediaPlayer mediaPlayer){
- MyMediaController.mediaPlayer=mediaPlayer ;
- };
- @Override
- public void play() throws RemoteException {
- // TODO Auto-generated method stub
- MyMediaController.play.execute();
- }
- @Override
- public void pause() throws RemoteException {
- // TODO Auto-generated method stub
- MyMediaController.pause.execute();
- }
- @Override
- public void stop() throws RemoteException {
- // TODO Auto-generated method stub
- MyMediaController.stop.execute();
- };
- }
3. 在Activity中得到Binder的方式,是通过Stub类的IMusicService.Stub.asInterface(binder)方法
- private ServiceConnection myServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder binder) {
- musicServiceInterface = IMusicService.Stub.asInterface(binder);
- Log.d(TAG, " onServiceConnected");
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- musicServiceInterface = null;
- Log.d(TAG, " onServiceDisconnected");
- }
- };
本文转自 最牛傻蛋 51CTO博客,原文链接:http://blog.51cto.com/zuiniuwang/718309,如需转载请自行联系原作者