Android下使用AIDL进行通信

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

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

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

Android下使用AIDL进行通信_第1张图片                  Android下使用AIDL进行通信_第2张图片

那么下面我们来说说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();
	
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return mBinder;
	}

	private class ServiceBindler extends AidlService.Stub {

		public int add(int a, int b) throws RemoteException {

			return a + b;
		}

	}

}
之后就需要在清单文件中配置该service,因为这是四大组件之一,那么这个意图在后面需要用到,这里先定义好。

        
            
                
            
        
下面就开始写另一个和它进行通信的运用:

main.xml文件如下:




    
    
    
下面是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);
		}
	};

	@Override
	public 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 block
					e.printStackTrace();
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		});
	}

	private void startService() {
		Intent intent = new Intent();
		//这个Action就是在另一个应用的清单文件中配置的
		intent.setAction("cn.com.feng.service");
		bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if(conn != null){
			unbindService(conn);
			conn = null;
		}
	}
}
然后将这两个运行到手机上,就可以看见效果了。

Android下使用AIDL进行通信_第3张图片





你可能感兴趣的:(Android)