首页 > 代码库 > android AIDL的一些写法

android AIDL的一些写法

Service这边只要定义一个服务:

 <service  android:name=".BaseTypeService">
            <intent-filter >
                <action android:name="cn.bgxt.Service.BASE_TYPE_SERVICE"/>
            </intent-filter>
            
        </service>

对于传递的是基本类型:创建要传递的数据类型:

interface IDog{
	String getName();
	int getAge();	
}

然后在服务器的Service上创建Stub,Stub是存根的意思,在客户端也有一个一样的IDog类,通信的时候传递的都是IDog类型:

服务端Service的写法:

import com.example.aidlservicedemo.domain.IDog.Stub;

public class BaseTypeService extends Service {
	private final String TAG="main";
	private DogBinder binder=null;
	private String[] names=new String[]{"小白","旺财","小黑"};
	private int[] ages=new int[]{1,2,3};
	
	/**
	 * Stub的实现类,Stub内部实现了Binder
	 * 内部实现AIDL定义的方法
	 */
	public class DogBinder extends Stub{

		@Override
		public String getName() throws RemoteException {
			<strong>return names[0];</strong>
		}

		@Override
		public int getAge() throws RemoteException {
			<strong>return ages[1];</strong>
		}		
	}
	
	
	@Override
	public void onCreate() {
		super.onCreate();
		// 实例化Binder对象
		binder=new DogBinder();
		Log.i(TAG, "创建服务成功");
	}

	@Override
	public IBinder onBind(Intent intent) {
		Log.i(TAG, "绑定服务成功");
		// 返回Binder对象
		return binder;
	}
}

客户端这样来调用:

public class BaseTypeActivity extends Activity {
	private Button btn_startService, btn_endService,btn_getServiceData;
	private IDog dogService;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_service);

		btn_startService = (Button) findViewById(R.id.btn_startService);
		btn_endService = (Button) findViewById(R.id.btn_endService);
		btn_getServiceData = (Button) findViewById(R.id.btn_getServiceData);

		btn_startService.setOnClickListener(click);
		btn_endService.setOnClickListener(click);
		btn_getServiceData.setOnClickListener(click);
	}

	private View.OnClickListener click = new OnClickListener() {

		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btn_startService:
				startService();
				break;
			case R.id.btn_endService:
				endService();
				break;
			case R.id.btn_getServiceData:
				getServiceDate();
				break;
			}
		}				
	};
	/*
	 * 获取数据
	 */
	private void getServiceDate() {
		try {
			if(dogService!=null){
				<strong>StringBuilder sBuilder=new StringBuilder();
				sBuilder.append("name:"+dogService.getName());
				sBuilder.append("\nage:"+dogService.getAge());//获取数据,这个结果应该是小白,2</strong>
				Toast.makeText(BaseTypeActivity.this, sBuilder.toString(), Toast.LENGTH_SHORT).show();
			}
			else
			{
				Toast.makeText(BaseTypeActivity.this, "请先绑定服务", Toast.LENGTH_SHORT).show();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}		
	}

	private ServiceConnection connBase=new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			dogService=null;
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// IDog.Stub.asInterface,获取接口
			<strong>dogService=IDog.Stub.asInterface(service);//表示拿到的这个Service对象</strong>
		}
	};
	
	/**
	 * 开始服务
	 */
	private void startService(){
		<strong>Intent intent=new Intent();
		intent.setAction("cn.bgxt.Service.BASE_TYPE_SERVICE");//这个必须跟服务端menufest上的action一致
		bindService(intent, connBase, BIND_AUTO_CREATE);
		Toast.makeText(BaseTypeActivity.this, "开始绑定服务", Toast.LENGTH_SHORT).show();</strong>
	}
	/**
	 * 停止服务
	 */
	private void endService(){
		if(connBase!=null)
		{
			unbindService(connBase);
			Toast.makeText(BaseTypeActivity.this, "服务解除绑定", Toast.LENGTH_SHORT).show();
		}
	}	
}


如果AIDL通讯传递是自定义类型:

一个常用的根据user来返回对象message信息的例子,user ,message都是自定义类型:

public class Message implements Parcelable {

	private int id;
	private String msgText;
	private String fromName;
	private String date;
}
public class User implements Parcelable {
	
	
	private int id;
	private String username;
	private String password;
}

定义两个AIDL文件

message.aidl:

parcelable Message; 

user.aidl

parcelable User; 

服务器代码:

public class CustomTypeService extends Service {
	private static final String TAG = "main";
	private MsgBinder msgBinder = null;
	private static Map<User, List<Message>> map = new HashMap<User, List<Message>>();
	static {
		for (int i = 0; i < 3; i++) {
			User user = new User(i, "jack" + i, "99" + i);
			List<Message> messages = new ArrayList<Message>();
			Message msg = null;
			if (i == 0) {
				msg = new Message(i, "这两天好吗?", "Jerry",
						new Date().toGMTString());
				messages.add(msg);
			}
			map.put(user, messages);
		}
	}

	public class MsgBinder extends Stub {

		@Override
		public List<Message> getMes(User us) throws RemoteException {
			for (Map.Entry<User, List<Message>> msgs : map.entrySet()) {
				if (msgs.getKey().getUsername().equals(us.getUsername())
						&& msgs.getKey().getPassword().equals(us.getPassword())) {
					Log.i(TAG, "找到信息了");
					return msgs.getValue();
				}
			}
			Log.i(TAG, "没找到信息了");
			return map.get(us);
		}

	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return msgBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		msgBinder = new MsgBinder();
	}

	@Override
	public void onDestroy() {
		msgBinder = null;
		super.onDestroy();
	}

}

客户端基本是一致的:

private static User[] users = new User[] {
			new User(0, "jack0", "990")};
	
/**
	 * 获取其他线程服务数据
	 */
	private void getServiceDate(){
		try {
			List<Message> msgs=getMsg.getMes(users[0]);
			StringBuilder sBuilder=new StringBuilder();
			for(Message msg:msgs){
				sBuilder.append(msg.toString()+"\n");
			}
			Toast.makeText(CustomTypeActivity.this, sBuilder.toString(), Toast.LENGTH_SHORT).show();
		} catch (Exception e) {
			Toast.makeText(CustomTypeActivity.this, "获取数据出错", Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		}
	}