Android下使用AIDL进行通信

来源:互联网 发布:淘宝企业店铺开店要求 编辑:程序博客网 时间:2024/05/20 11:23

aidl是 Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。还有一个就是IPC(inter process communication),表示的进程间通信。

这编博客就是一个入门的例子,告诉我们大家如何使用AIDL通信。好了废话不多说,现在就开始进入我们的例子:

首先我们需要新建两个工程,然后再两个工程内都存放一个相同的AIDL文件,如下图:

                  

那么下面我们来说说AIDL文件是如何编写的,其实也很简单,大家可以把它看成一个interface,只不过这个InterFace比较特殊,它里面不能用修饰符(比如说public,protected,private)。

AidlService.aidl文件如下:

package cn.com.aidl.service;interface AidlService{int add(in int a,in int b);}
当那保存好后,就会在gen目录下自动创建一个java文件,那么在该java文件的内部会有一个stub内部类,这个类是比较重要的。

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: D:\\workspace\\Androidworkspace\\ZAIDLService\\src\\cn\\com\\aidl\\service\\AidlService.aidl */package cn.com.aidl.service;public interface AidlService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements cn.com.aidl.service.AidlService{private static final java.lang.String DESCRIPTOR = "cn.com.aidl.service.AidlService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an cn.com.aidl.service.AidlService interface, * generating a proxy if needed. */public static cn.com.aidl.service.AidlService 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 cn.com.aidl.service.AidlService))) {return ((cn.com.aidl.service.AidlService)iin);}return new cn.com.aidl.service.AidlService.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_add:{data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();int _arg1;_arg1 = data.readInt();int _result = this.add(_arg0, _arg1);reply.writeNoException();reply.writeInt(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements cn.com.aidl.service.AidlService{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 int add(int a, int b) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(a);_data.writeInt(b);mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);_reply.readException();_result = _reply.readInt();}finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public int add(int a, int b) throws android.os.RemoteException;}
其实这个类对于刚刚接触的人来说,可能有点复杂,里面做了以下几件事,1、判断当前的应用和通信的应用是否是在同一个进程中;2、会创建一个代理对象 ;     3、主要是通过onTransact()方法来调用远程的方法

那么这些具体的是如何进行的,大家可以去网上百度Aidl源码分析,就可以找到哦!

之后我们就需要新建一个Service,在这个Service内部返回一个AidlService的对象。我们也需要继承这个stub类。

AddService.java代码如下:

package cn.com.aidl.service;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class AddService extends Service {private ServiceBindler mBinder = new ServiceBindler();@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stubreturn mBinder;}private class ServiceBindler extends AidlService.Stub {public int add(int a, int b) throws RemoteException {return a + b;}}}
之后就需要在清单文件中配置该service,因为这是四大组件之一,那么这个意图在后面需要用到,这里先定义好。

        <service android:name="cn.com.aidl.service.AddService">            <intent-filter >                <action android:name="cn.com.feng.service"/>            </intent-filter>        </service>
下面就开始写另一个和它进行通信的运用:

main.xml文件如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <EditText        android:id="@+id/first"         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:hint="请输入一个整数"        android:numeric="integer"/>    <EditText        android:id="@+id/second"         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:hint="请输第二个整数"        android:numeric="integer"/>    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="计算两个数的和" />        <TextView          android:id="@+id/textview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></LinearLayout>
下面是MainActivity,在这个Activity中,第一是要获得ServiceConnection对象,然后覆盖onServiceConnected()方法,在这个方法中获得AidlService的对象,用于后面调用。

package cn.com.aidl;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import cn.com.aidl.service.AidlService;public class MainActivity extends Activity {private EditText first, second;private TextView textView;private Button button;private AidlService mService;//获取到service对象private ServiceConnection conn = new ServiceConnection() {public void onServiceDisconnected(ComponentName name) {mService = null;}public void onServiceConnected(ComponentName name, IBinder service) {mService = AidlService.Stub.asInterface(service);}};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);first = (EditText) this.findViewById(R.id.first);second = (EditText) this.findViewById(R.id.second);textView = (TextView) this.findViewById(R.id.textview);button = (Button) this.findViewById(R.id.button);//开启服务startService();button.setOnClickListener(new OnClickListener() {public void onClick(View v) {String a = first.getText().toString();String b = second.getText().toString();try {int i = mService.add(Integer.parseInt(a),Integer.parseInt(b));textView.setText(a + " + " + b + " = " + i);} catch (NumberFormatException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}private void startService() {Intent intent = new Intent();//这个Action就是在另一个应用的清单文件中配置的intent.setAction("cn.com.feng.service");bindService(intent, conn, Context.BIND_AUTO_CREATE);}@Overrideprotected void onDestroy() {super.onDestroy();if(conn != null){unbindService(conn);conn = null;}}}
然后将这两个运行到手机上,就可以看见效果了。







0 0
原创粉丝点击