Android之AIDL使用解析

我们都知道android程序内的数据共享比较容易理解,毕竟在一个程序内。但如果android程序与程序之间应该如何共享并传递数据呢?毕竟一个程序不能访问另一个程序的内存空间,因此android提供了AIDL工具来将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界,在不同程序间传递。具体使用方法如下:

(一)创建服务器端程序,发送数据的一方。


1、创建.aidl文件

IAIDLServerService.aidl:

package com.jackchan.aidlserver;

import com.jackchan.aidlserver.Book;
interface IAIDLServerService{
	String sayHello();
	
	Book getBook();
}



该aidl文件里声明一个接口,该接口包含一些方法,这些方法所带的参数和返回值必须为以下类型:
1)、java语言的所有基本类型,如int float long char boolean 等;
2)、String CharSequence List Map,其中List和Map里的元素也必须是1)和2)所说的这些数据类型或者其他你定义的.aidl数据接口和Parcelable对象。
例如这里的Book返回值就是一个Parcelable对象,它的代码如下:

Book.java:


package com.jackchan.aidlserver;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable{
	
	private String bookName;
	private int bookPrice;
	
	public Book(){
		
	}
	public Book(Parcel parcel){
		bookName = parcel.readString();
		bookPrice = parcel.readInt();
	}
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public int getBookPrice() {
		return bookPrice;
	}
	public void setBookPrice(int bookPrice) {
		this.bookPrice = bookPrice;
	}
	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// TODO Auto-generated method stub
		dest.writeString(bookName);
		dest.writeInt(bookPrice);
	}
	
	public static final Parcelable.Creator CREATOR = new Creator(){

		@Override
		public Book createFromParcel(Parcel source) {
			// TODO Auto-generated method stub
			return new Book(source);
		}

		@Override
		public Book[] newArray(int size) {
			// TODO Auto-generated method stub
			return new Book[size];
		}
		
	};
}



Book.aidl:

parcelable Book;

这里你会发现gen里的文件夹会自动生成一些文件,这些文件不用去修改它。
2、实现你刚刚定义的接口
我们刚刚在.aidl里定义的接口会有一个Stub的子类(yourInterface.Stub),我们新建一个类继承自Service,并在这个类中复写刚刚.aidl里的抽象方法。


package com.jackchan.aidlserver;

import com.jackchan.aidlserver.IAIDLServerService.Stub;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class AidlServerService extends Service{
	
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return mBinder;
	}
	
	private IAIDLServerService.Stub mBinder = new Stub(){
			
		@Override
		public String sayHello() throws RemoteException {
			return "Hello";
		}
		
		@Override
		public Book getBook() throws RemoteException {
			Book mBook = new Book();
			mBook.setBookName("Android应用开发");
			mBook.setBookPrice(50);
			return mBook;
		}
	};
}


这里的IAIDLServerService.Stub其实也是一个IBinder的子类,因此我们可以把他作为Service的onBind的返回值,一旦这个Service被其他程序的服务绑定,就将这个IBinder类实例发送出去,同样这个实例里重写的方法数据也跟着一起发送出去。
运行服务器端如下效果(首界面我们不做任何处理)








以上就是我们服务器端发送数据的代码,接下来我们看看怎么进行接收。
(二)创建客户端程序



1、首先得把服务器程序里关于要共享数据的接口的代码连同包一起拷过来(上图红框部分)。
2、当客户端调用bindService()方法就将绑定到指定Service,


Intent service = new Intent("com.jackchan.aidlserver.IAIDLServerService");
				bindService(service, mConnection, BIND_AUTO_CREATE);


并且客户端的OnServiceConnected()方法里调用IAIDLServerService.Stub.asInterface()将得到服务器端OnBind方法里IBinder类实例


@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			
			mIaidServerService = IAIDLServerService.Stub.asInterface(service);			
			try{
				String mText = "Say Hello:" + mIaidServerService.sayHello() + "\n";
				mText += "书名:" + mIaidServerService.getBook().getBookName() + "\n";
				mText += "价格:" + mIaidServerService.getBook().getBookPrice();
				mTextView.setText(mText);
			}
			catch(RemoteException e){
				e.printStackTrace();
			}
		}



整个客户端完整代码如下:


package com.jackchan.aidlclient;

import com.jackchan.aidlserver.IAIDLServerService;

import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class AIDLClientActivity extends Activity {
	
	private TextView mTextView;
	private Button mButton;
	
	private IAIDLServerService mIaidServerService = null;
	
	private ServiceConnection mConnection = new ServiceConnection(){

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			
			mIaidServerService = IAIDLServerService.Stub.asInterface(service);			
			try{
				String mText = "Say Hello:" + mIaidServerService.sayHello() + "\n";
				mText += "书名:" + mIaidServerService.getBook().getBookName() + "\n";
				mText += "价格:" + mIaidServerService.getBook().getBookPrice();
				mTextView.setText(mText);
			}
			catch(RemoteException e){
				e.printStackTrace();
			}
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			mIaidServerService = null;
		}
		
		
	};
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mTextView = (TextView)findViewById(R.id.textview);
        mButton = (Button)findViewById(R.id.button);
        
        mButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent service = new Intent("com.jackchan.aidlserver.IAIDLServerService");
				bindService(service, mConnection, BIND_AUTO_CREATE);
			}
		});
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

其中布局文件代码如下:




      
	


最后客户端效果图如下:





 
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(android)