您的位置:首页 > 移动开发 > Android开发

Android接口定义语言---AIDL(四)

2012-08-24 10:44 387 查看
调用IPC方法

以下是调用AIDL所定义的远程接口的必须的步骤:

1. 在工程的src/目录中包含对应的.aidl文件;

2. 声明IBinder接口(基于AIDL生成的)的一个实例;

3. 实现ServiceConnection接口;

4. 调用Context.bindService()方法,并传入ServiceConnection接口的实现;

5. 在onServiceConnected()方法的实现中,会接收到一个IBinder实例(叫做service)。调用YourInterfaceName.Stub.asInterface((IBider)service)方法把要返回的参数转换成YourInterfaceType;

6. 调用在接口中定义的方法。应该始终扑捉DeadObjectException异常,在连接被中断时会抛出这个异常。这是由远程方法所抛出的唯一异常;

7. 调用接口实例的Context.unbindService()方法来取消连接;

调用IPC服务的几点意见:

1. 对象是跨进程被引用计数的;

2. 能够发送匿名对象作为方法参数。

关于绑定服务的更多信息,请看“绑定服务”的文档.

http://developer.android.com/guide/components/bound-services.html#Binding

下面的示例代码演示了调用远程创建的AIDL服务,这个远程服务的例子在ApiDemos工程中:

public static class Binding extends Activity {

   
/** The primary interface we will be calling on the service. */

   
IRemoteService mService = null;

   
/** Another interface we use on the service. */

   
ISecondary mSecondaryService = null;

 

   
Button mKillButton;

   
TextView mCallbackText;

 

   
private boolean mIsBound;

 

   
/**

    
* Standard initialization of this activity.  Set up the UI, then wait

    
* for the user to poke it before doing anything.

    
*/

   
@Override

   
protected void onCreate(Bundle savedInstanceState) {

       
super.onCreate(savedInstanceState);

 

       
setContentView(R.layout.remote_service_binding);

 

       
// Watch for button clicks.

       
Button button = (Button)findViewById(R.id.bind);

       
button.setOnClickListener(mBindListener);

       
button = (Button)findViewById(R.id.unbind);

       
button.setOnClickListener(mUnbindListener);

       
mKillButton = (Button)findViewById(R.id.kill);

       
mKillButton.setOnClickListener(mKillListener);

       
mKillButton.setEnabled(false);

 

       
mCallbackText = (TextView)findViewById(R.id.callback);

       
mCallbackText.setText("Not attached.");

   
}

 

   
/**

    
* Class for interacting with the main interface of the service.

    
*/

   
private ServiceConnection mConnection = new ServiceConnection() {

       
public void onServiceConnected(ComponentName className,

               
IBinder service) {

           
// This is called when the connection with the service has been

           
// established, giving us the service object we can use to

           
// interact with the service.  We are communicating with our

           
// service through an IDL interface, so get a client-side

           
// representation of that from the raw service object.

           
mService = IRemoteService.Stub.asInterface(service);

           
mKillButton.setEnabled(true);

           
mCallbackText.setText("Attached.");

 

           
// We want to monitor the service for as long as we are

           
// connected to it.

           
try {

               
mService.registerCallback(mCallback);

           
} catch (RemoteException e) {

               
// In this case the service has crashed before we could even

               
// do anything with it; we can count on soon being

               
// disconnected (and then reconnected if it can be restarted)

               
// so there is no need to do anything here.

           
}

 

           
// As part of the sample, tell the user what happened.

           
Toast.makeText(Binding.this, R.string.remote_service_connected,

                   
Toast.LENGTH_SHORT).show();

       
}

 

       
public void onServiceDisconnected(ComponentName className) {

           
// This is called when the connection with the service has been

           
// unexpectedly disconnected -- that is, its process crashed.

           
mService = null;

           
mKillButton.setEnabled(false);

           
mCallbackText.setText("Disconnected.");

 

           
// As part of the sample, tell the user what happened.

           
Toast.makeText(Binding.this, R.string.remote_service_disconnected,

                   
Toast.LENGTH_SHORT).show();

       
}

   
};

 

   
/**

    
* Class for interacting with the secondary interface of the service.

    
*/

   
private ServiceConnection mSecondaryConnection = new ServiceConnection() {

       
public void onServiceConnected(ComponentName className,

               
IBinder service) {

           
// Connecting to a secondary interface is the same as any

           
// other interface.

           
mSecondaryService = ISecondary.Stub.asInterface(service);

           
mKillButton.setEnabled(true);

       
}

 

       
public void onServiceDisconnected(ComponentName className) {

           
mSecondaryService = null;

           
mKillButton.setEnabled(false);

       
}

   
};

 

   
private OnClickListener mBindListener = new OnClickListener() {

       
public void onClick(View v) {

           
// Establish a couple connections with the service, binding

           
// by interface names.  This allows other applications to be

           
// installed that replace the remote service by implementing

           
// the same interface.

           
bindService(new Intent(IRemoteService.class.getName()),

                   
mConnection, Context.BIND_AUTO_CREATE);

    
       bindService(new Intent(ISecondary.class.getName()),

                   
mSecondaryConnection, Context.BIND_AUTO_CREATE);

           
mIsBound = true;

           
mCallbackText.setText("Binding.");

       
}

   
};

 

   
private OnClickListener mUnbindListener = new OnClickListener() {

       
public void onClick(View v) {

           
if (mIsBound) {

               
// If we have received the service, and hence registered with

               
// it, then now is the time to unregister.

               
if (mService != null) {

                   
try {

                       
mService.unregisterCallback(mCallback);

                   
} catch (RemoteException e) {

                       
// There is nothing special we need to do if the service

           
            // has crashed.

                   
}

               
}

 

               
// Detach our existing connection.

               
unbindService(mConnection);

               
unbindService(mSecondaryConnection);

               
mKillButton.setEnabled(false);

               
mIsBound = false;

               
mCallbackText.setText("Unbinding.");

           
}

       
}

   
};

 

   
private OnClickListener mKillListener = new OnClickListener() {

       
public void onClick(View v) {

           
// To kill the process hosting our service, we need to know its

           
// PID.  Conveniently our service has a call that will return

           
// to us that information.

           
if (mSecondaryService != null) {

               
try {

                   
int pid = mSecondaryService.getPid();

                   
// Note that, though this API allows us to request to

                   
// kill any process based on its PID, the kernel will

                   
// still impose standard restrictions on which PIDs you

                   
// are actually able to kill.  Typically this means only

                   
// the process running your application and any additional

                   
// processes created by that app as shown here; packages

                   
// sharing a common UID will also be able to kill each

                   
// other's processes.

                   
Process.killProcess(pid);

                   
mCallbackText.setText("Killed service process.");

               
} catch (RemoteException ex) {

                   
// Recover gracefully from the process hosting the

                   
// server dying.

                   
// Just for purposes of the sample, put up a notification.

                   
Toast.makeText(Binding.this,

               
            R.string.remote_call_failed,

                           
Toast.LENGTH_SHORT).show();

               
}

           
}

       
}

   
};

 

   
// ----------------------------------------------------------------------

   
// Code showing how to deal with callbacks.

   
// ----------------------------------------------------------------------

 

   
/**

    
* This implementation is used to receive callbacks from the remote

    
* service.

    
*/

   
private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {

       
/**

        
* This is called by the remote service regularly to tell us about

        
* new values.  Note that IPC calls are dispatched through a thread

        
* pool running in each process, so the code executing here will

        
* NOT be running in our main thread like most other things -- so,

        
* to update the UI, we need to use a Handler to hop over there.

        
*/

       
public void valueChanged(int value) {

           
mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));

       
}

   
};

 

   
private static final int BUMP_MSG = 1;

 

   
private Handler mHandler = new Handler() {

       
@Override public void handleMessage(Message msg) {

           
switch (msg.what) {

               
case BUMP_MSG:

                   
mCallbackText.setText("Received from service: " + msg.arg1);

                   
break;

               
default:

                   
super.handleMessage(msg);

           
}

       
}

 

   
};

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息