Android中不使用AIDL实现Service的远程调用

优点:Client端与Server端的DESCRIPTOR可以自定义,不受包名限制

实质中其实是使用底层Binder机制提供的Java层接口 Binder 、IInterface等去实现

客户端中使用transact发起进程间通信请求,服务端会回调onTransact来处理请求

Common Interface:

public interface ITimeCountService {
	int getCount() throws RemoteException;
} 

Server:

public abstract class TimeCountStub extends android.os.Binder implements
		IInterface, ITimeCountService {
	private static final java.lang.String DESCRIPTOR = "com.example.servicedemo.nonaidl.ITimeCountService";

	/** Construct the stub at attach it to the interface. */
	public TimeCountStub() {
		this.attachInterface(this, DESCRIPTOR);
	}

	@Override
	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_getCount: {
			data.enforceInterface(DESCRIPTOR);
			int _result = this.getCount();
			reply.writeNoException();
			reply.writeInt(_result);
			return true;
		}
		}
		return super.onTransact(code, data, reply, flags);
	}

	static final int TRANSACTION_getCount = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}

Client:

public class TimeCountProxy implements /*IInterface,*/ ITimeCountService {
	private static final java.lang.String DESCRIPTOR = "com.example.servicedemo.nonaidl.ITimeCountService";
	private android.os.IBinder mRemote;

	TimeCountProxy(android.os.IBinder remote) {
		mRemote = remote;
	}

//	@Override
//	public android.os.IBinder asBinder() {
//		return mRemote;
//	}

	public java.lang.String getInterfaceDescriptor() {
		return DESCRIPTOR;
	}

	/**
	 * Cast an IBinder object into an
	 * com.example.servicedemo.nonaidl.ITimeCountService interface, generating a
	 * proxy if needed.
	 */
	public static ITimeCountService asInterface(
			android.os.IBinder obj) {
		if ((obj == null)) {
			return null;
		}
		android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
		if (((iin != null) && (iin instanceof ITimeCountService))) {
			return ((ITimeCountService) iin);
		}
		return new TimeCountProxy(obj);
	}

	@Override
	public int getCount() 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);
			mRemote.transact(TimeCountStub.TRANSACTION_getCount, _data, _reply,
					0);
			_reply.readException();
			_result = _reply.readInt();
		} finally {
			_reply.recycle();
			_data.recycle();
		}
		return _result;
	}
}

Service中片段:

public class TimeCountService extends Service {

	...

	TimeCountStub stub = new TimeCountStub() {

		@Override
		public int getCount() throws RemoteException {
			return count;
		}
	};

	@Override
	public IBinder onBind(Intent intent) {
		Log.i(TAG, "onBind");
		return stub;
	}

	...

}

Client中片段:

public class MainActivity extends Activity {

	...

	private ITimeCountService timeCountService;

	private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			Log.i(TAG, "onServiceConnected");
			timeCountService = TimeCountProxy.asInterface(service);

			Log.i(TAG, "timeCountService: " + timeCountService);

			canTimeUpdateTaskRunning = true;
			TimeUpateTask t = new TimeUpateTask();
			t.execute(new Object());

			Log.i(TAG, "task status: " + t.getStatus());
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			Log.i(TAG, "onServiceDisconnected");
		}
	};

	...

}
时间: 2024-11-08 13:09:43

Android中不使用AIDL实现Service的远程调用的相关文章

Android中bindService的使用及Service生命周期

Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法,本文只探讨纯bindService的使用,不涉及任何startService方法调用的情况.如果想了解startService相关的使用,请参见<Android中startService的使用及Service生命周期>. bindService启动服务的特点 相比于用startService启动的Service,bindService启动的服务

Android中实现开机自动启动服务(service)实例

最近在将 HevSocks5Client 移植到 Android 上了,在经过增加 signalfd 和 timerfd 相关的系统调用支持后,就可以直接使用 NDK 编译出 executable 了.直接的 native exectuable 在 Android 系统总还是不太方便用哦.还是做成一个 apk 吧,暂定只写一个 service 并开机自动启用,无 activity 的. Java 中调用 native 程序我选择使用 JNI 方式,直接在 JNI_OnLoad 方法中调用 pth

Android中startService的使用及Service生命周期

Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法,本文只探讨startService的使用,不涉及任何bindService方法调用的情况. 当我们通过调用了Context的startService方法后,我们便启动了Service,通过startService方法启动的Service会一直无限期地运行下去,只有在外部调用Context的stopService或Service内部调用Servic

Android中使用&quot;running services&quot;查看service进程内存

从Android 2.0开始,在Settings中加入了一个新的activity("Running Services" activity),它用于显示当前运行的每个Services进程的内存使用情况及整个手机的内存大致使用情况.可以通过Setting->Applications->Running services进入该activity. Running Services界面如下: 图1: Running Services主要是当前正在运行的Services进程的一个列表.

Android 中 判断给出的service是否是在运行中

public static boolean isServiceRunning(Context mContext, String className) { boolean isRunning = false; ActivityManager activityManager = (ActivityManager) mContext .getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo>

android中webView加载H5,JS不能调用问题的解决

使用了html5 页面,使用webView加载后发现 超链接的锚点不可以用 为webView设置下面两句就好了: mWebView.getSettings().setDomStorageEnabled(true);mWebView.getSettings().setDatabaseEnabled(true); 原文地址:https://www.cnblogs.com/netcorner/p/8207212.html

Android 中的 Service 全面总结详解【下】

上一篇文章Android 中的 Service 全面总结详解[下] 介绍了Service的一些知识以及本地Service的使用,如果对Service还不太了解的建议先看下上篇文章:本文主要接着上一篇讲下远程服务的使用: 在说到远程服务的时候,我们需要先了解一些预备的知识: 首先来了解一下AIDL机制: AIDL的作用 由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运行另一个服务进程,而且经常会在不同的进程间传递对象.在Android平台,一个进程通常不能访问另一个进程的内存空间,

Android中通过Messenger与Service实现进程间双向通信

Android中的Service和其调用者既可以在同一个App中,也可以在不同的App.如果Service在App1中,而调用Service的客户端在App2中,那么我们就可以用Service实现进程间的相互通信.本文将介绍如何通过bindService和Messenger实现进程间通信(IPC),如果对bindService绑定服务和Binder不熟悉,可参见<Android中bindService的使用及Service生命周期>,理解该博文是本文的基础. 让Service实现与其他进程通信

Android中如何查看内存

文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-android#2299813 像Linux这种现代操作系统的内存使用是很复杂的,因此很难准确的知道你的应用程序使用了好多内存. 查看内存使用的方式有很多种,但是各个方式查看到的结果可能会有微略不同. 方式一,Running services 通过手机上Running services的Activit