Android基础——AIDL进程间通信



与绑定本地的Service不同的是,本地Service的onBinde()方法会直接把IBinder对象本身传给客户端的ServiceConnection。但是远程Service的onBind()方法只是将IBinder对象的代理传给客户端的ServiceConnection。


Android的AIDL定义了两个进程之间的通信接口,它的语法也很简单,和Java的接口定义相似,不过有几点区别:
1,AIDL定义接口代码文件必须以.aidl结尾;
2,AIDL接口中用到的数据类型,除了基本数据类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即便是他们在同一个包中也需要导包;
3,接口中只能定义方法;


在定义完AIDL接口后,AndroidSDK的工具aidl.exe会将该接口实现,你好会在gen/目录的相同包路径下看到接口的实现类,在这个实现类中有一个Stub的内部类,该内部类实现了IBinder、和你定义的AIDL接口,这个Stub就是远程Service的回调类,作为onBind()方法的返回值。在这个接口中有一个静态的asInterface(...)方法,这个方法会返回一个IBinder对象的代理。

AIDL接口:

package com.flyingduck.servicedemo3;

interface ICommunication{
 String getServiceInfo();
}


Service端:

package com.flyingduck.servicedemo3;

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

public class AIDLService extends Service {

	
	private ICommunication.Stub comm = new ICommunication.Stub() {
		
		@Override
		public String getServiceInfo() throws RemoteException {
			return "I'm from AIDLService";
		}
	};
	
	@Override
	public IBinder onBind(Intent arg0) {
		return comm;
	}
}

Manifest.xml

        <service
            android:name="com.flyingduck.servicedemo3.AIDLService"
            android:process=":romote" >
        </service>


Client端:

既然AIDL定义了两个进程间的通信接口,所以我们必须保证在客户端和服务端都会同时拥有这个接口。

package com.flyingduck.servicedemo3;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
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.TextView;

public class ClientActivity extends Activity {

	private Button bindBtn;
	private Button unbindBtn;
	private TextView showTxt;
	
	private ServiceConnection conn;
	private ICommunication communication;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_client);
		
		bindBtn = (Button) findViewById(R.id.bind_service);
		unbindBtn = (Button) findViewById(R.id.un_bind_service);
		showTxt = (TextView) findViewById(R.id.show);
		
		conn = new ServiceConnection() {
			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				communication = ICommunication.Stub.asInterface(service);
				
				try {
					showTxt.setText(communication.getServiceInfo());
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
			@Override
			public void onServiceDisconnected(ComponentName name) {
				
			}

		};
		
		bindBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				bindService(new Intent(getApplicationContext(), AIDLService.class), conn, Service.BIND_AUTO_CREATE );
			}
		});
		
		unbindBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				unbindService(conn);
			}
		});
		
		
	}
}

这个例子简单的演示了AIDL的使用方法。实际上,服务需要接受不同应用的并发请求时才使用AIDL,如果我们只是想进行IPC(就是跨进程通信),并不需要处理多线程时,只需要使用 Messenger就可以了。


例子运行效果:



供参考文章:http://blog.csdn.net/saintswordsman/article/details/5130947


这里我们只是简单的传递了一个字符串,在进行跨进程通讯时,我们往往要传递一些较复杂的自定义类型,这时我们需要使用Android的序列化机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值