Android AIDL的实现

心已入冬 提交于 2019-12-09 13:43:07

      AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

【一】AIDL文件的创建:

     AIDL使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。这些参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。

     其中对于Java编程语言的基本数据类型 (int, long, char, boolean等),String和CharSequence,集合接口类型List和Map,不需要import 语句。 而如果需要在AIDL中使用其他AIDL接口类型,需要import,即使是在相同包结构下。AIDL允许传递实现Parcelable接口的类,需要import. 
     需要特别注意的是, 对于非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。

    AIDL只支持接口方法,不能公开static变量。

    其中AIDL的方法还提供了oneway这个关键字,可以用关键字oneway来标明远程调用的行为属性,使用了该关键字,那么远程调用将仅仅是调用所需的数据传输过来并立即返回,而不会等待结果的返回,也即是说不会阻塞远程线程的运行。AIDL接口将最终将获得一个从Binder线程池中产生的调用(和普通的远程调用类似)。如果关键字oneway在本地调用中被使用,将不会对函数调用有任何影响。  

    1.服务端接口的创建:

package com.liusl.aidl;
import com.liusl.aidl.AIDLCallback;
interface ServiceAIDL {
	void registerClient(AIDLCallback cb);
	void unregisterClient(AIDLCallback cb);
	int add(int i, int j);
	int sum(in int[] numbers);
}

    2.回调接口的创建:

package com.liusl.aidl;

interface AIDLCallback {

	int returnResult(int result);
}

【二】服务端接口的实现:

    将AIDLCallback作为服务端给客户端的回调,这样才实现了服务端和客户端的通信。同时使服务端继承service类,实现onBind方法,创建AIDLService对象,这样才能将服务端的接口提供给客户端进行调用。

package com.liusl.aidl;

import com.liusl.aidl.AIDLCallback;
import com.liusl.aidl.ServiceAIDL;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class MyAIDLService extends Service {

	public final String TAG = "[service]";
	int sum = 0;

	@Override
	public IBinder onBind(Intent intent) {
		Log.i(TAG, "[MyAIDLService] onBind(intent)...");
		return (IBinder) new ServiceAIDLImpl();
	}

	class ServiceAIDLImpl extends ServiceAIDL.Stub {

		private AIDLCallback cb;

		@Override
		public void registerClient(AIDLCallback cb) throws RemoteException {		
			this.cb = cb;
			Log.i(TAG, "[ServiceAIDLImpl] registerClient start...");
			cb.asBinder().linkToDeath(new DeathRecipient() {
				 @Override
				public void binderDied() {
					try {
						Log.i(TAG, "[ServiceAIDLImpl]binderDied.");
					} catch (Throwable e) {
					}
				}
			}, 0);

			Log.i(TAG, "[ServiceAIDLImpl] registerClient end...");
		}

		@Override
		public void unregisterClient(AIDLCallback cb) throws RemoteException {

		}

		@Override
		public int add(int i, int j) throws RemoteException {
			sum = 0;
			sum = i + j;
			cb.returnResult(sum);
			return 0;
		}

		@Override
		public int sum(int[] numbers) throws RemoteException {
			sum = 0;
			for (int i = 0; i < numbers.length; i++) {
				sum += numbers[i];
			}
			cb.returnResult(sum);
			return 0;
		}

	}
}


【三】服务的创建及Activity的实现:

         在客户端使用服务端的AIDL前,需要先通过创建一个客户端与服务端的连接,步骤如下:

    1.创建intent:

        String actionName = "com.liusl.aidl.MyAIDLService";

        Intent intent = new Intent(actionName)

    2.实现一个MyServiceConnection类,继承ServiceConnection,重写onServiceConnected和onServiceDisConnected方法。

    3.新建了BindService对象:

        MyServiceConnection connection = new MyServiceConnection();

        通过调用bindService(intent, connection, Context.BIND_AUTO_CREATE);->onServiceConnected(),在OnServiceConnected()中获取服务端得aidl对象,

        myservice = (ServiceAIDL) ServiceAIDL.Stub.asInterface(service);

    4.实现客户端的AIDLCallback接口:

private class AIDLCallbackImpl extends AIDLCallback.Stub {

		public int returnResult(int result) {
    			textView.setText("Result :" + result);
			return result;
		}
	}

    5.通过服务端的aidl对象调用服务端的注册方法以及其他的方法:

    myservice.registerClient(callBack);

    myservice.add(2, 3);

    由此就完成了客户端注册一个客户到服务端并且调用服务端的add方法,服务端将add的结果反馈给回调方法,客户端在接收到回调传来的值后进行显示操作。

注意:需要在AndroidMainFest.xml中对服务进行注册:

<service android:name="com.liusl.aidl.MyAIDLService">
       	<intent-filter>
        	<action android:name="com.liusl.aidl.MyAIDLService"/>
       	</intent-filter>
 </service>

代码所在位置:

http://www.oschina.net/code/snippet_1051613_22116

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!