跨进程调用Service(AIDL服务)

在过去的技术中,Corba可以实现跨进程的调用;在Java技术中,RMI也可以实现跨进程的调用;在Android中类似可以使用AIDL服务跨进程调用Service。

Android的远程Service调用与Java的RMI基本相似,一样都是先定义一个远程调用接口,然后为该接口提供一个实现类即可。与RMI不同的是,客户端访问Service时,Android并不是直接返回Service对象给客户端。

在Android中绑定本地Service时,返回的是一个IBinder对象;而访问远程Service时,是将IBinder的代理返回给客户端,当客户端获得IBinder对象的代理后,就可以通过IBinder对象去回调远程Service的属性和方法了。

示例如下:

创建AIDL文件:

AIDL:指Android Interface Definition Language

注意:AIDL定义接口的源代码必须以.aidl结尾;

AIDL接口中用到的数据类型,除了基本类型、String、List 、Map、CharSequence之外,其他类型都需要导包,即使在同一包中也需导包。

在Service端和客户端都需要为该接口提供实现。使用ADT工具进行开发,会自动为AIDL接口生成实现。

这是AIDL源代码的一个简单例子:

package com.lovo.service;
interface IMessage{
	int getFlag();
	String getMessage(String msg);
}

自动生成的AIDL实现,在此不给出。


远程的Service:

package com.lovo.service;

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

public class RemoteService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		MyMessage message = new MyMessage();
		return message;
	}
}

MyMessage类(IMessage的实现类):

package com.lovo.service;

public class MyMessage extends IMessage.Stub {
	@Override
	public int getFlag() {
		return 100;
	}

	@Override
	public String getMessage(String msg) {
		return msg + "Android!";
	}
}

 

客户端的Activity:

package com.lovo.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.lovo.conn.RemoteServiceConnection;
import com.lovo.lesson10.R;

public class StartRemoteActivity extends Activity {
	private Button startServiceBtn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.remote_main);
		startServiceBtn = (Button) findViewById(R.id.remote_main_btn_startserver);
		startServiceBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setAction("com.lovo.service.REMOTE_SERVICE");
				bindService(intent, new RemoteServiceConnection(),
						BIND_AUTO_CREATE);
			}
		});
	}
}


客户端的ServiceConnection的实现类(RemoteServiceConnection):

package com.lovo.conn;

import com.lovo.service.IMessage;

import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class RemoteServiceConnection implements ServiceConnection {

	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
		// 将远程的代理对象转换成真实对象
		IMessage message = IMessage.Stub.asInterface(service);
		try {
			Log.i("访问远程方法:",
					message.getFlag() + " " + message.getMessage("I like "));
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onServiceDisconnected(ComponentName name) {

	}

}

布局文件只有一个按钮在此省略不写。本文只是简单地调用了远程的方法,在实际中可以使用AIDL传递复杂数据。


你可能感兴趣的:(android,AIDL服务,访问远程Service)