android进程间通信(远程服务aidl,服务端)

android进程间通信,使用service,调用bindService来绑定服务,本例实现双向通信。

服务端


可以看到有三个aidl文件,是实现进程间通信必须的。

Iservice.aidl文件:服务要使用此文件产生的stub,调用方法的参数必须是基本数据类型,list,parcel(如EntityData)类型的

package com.hm.aidl;

import com.hm.aidl.ICallback;
import com.hm.aidl.EntityData;

interface IService
{
    EntityData getCurrentData();
    List<EntityData> getDatas();
    void registerCallback(in ICallback callback);
}

ICallback.aidl文件:用于回调,服务端通知客户端

package com.hm.aidl;

import android.os.Bundle;

interface ICallback
{
    void notify(String action, in Bundle bundle);
}

EntityData.java文件:EntityData必须是Parcelablel类型

package com.hm.aidl;

import android.os.Parcel;
import android.os.Parcelable;

public class EntityData implements Parcelable {

    public int id;
    public String name;

    public EntityData() {

    }

    private EntityData(Parcel in) {
        id = in.readInt();
        name = in.readString();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(id);
        out.writeString(name);

    }

    public static final Parcelable.Creator<EntityData> CREATOR = new Parcelable.Creator<EntityData>() {
        public EntityData createFromParcel(Parcel in) {
            return new EntityData(in);
        }

        public EntityData[] newArray(int size) {
            return new EntityData[size];
        }
    };

}
另外也要创建一个EntityData.aidl文件,声明一下

package com.hm.aidl;

parcelable EntityData;

以上已经准备好通信的数据和接口,接下来就是创建服务MyService

首先在Manifest中注册

<service
            android:name="com.example.server.MyService"
            android:enabled="true"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.HM_SERVICE" />
            </intent-filter>
        </service>

接下来看MyService.java文件

package com.example.server;

import java.util.ArrayList;
import java.util.List;
import com.hm.aidl.EntityData;
import com.hm.aidl.ICallback;
import com.hm.aidl.IService;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class MyService extends Service {

	private static final String TAG = "Whuthm Service";

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

	static class IServiceImpl extends IService.Stub {

		ICallback mCallback;

		List<EntityData> mDatas;
		int mIndex = -1;

		public IServiceImpl() {
			mDatas = new ArrayList<EntityData>();
			for (int i = 0; i < 5; i++) {
				EntityData data = new EntityData();
				data.id = i;
				data.name = "EntityData " + i;
				mDatas.add(data);
			}
		}

		@Override
		public EntityData getCurrentData() throws RemoteException {
			Log.i(TAG, "getCurrentData");
			int size = mDatas != null ? mDatas.size() : 0;
			EntityData data = null;
			if (mIndex >= 0 && mIndex < size) {
				data = mDatas.get(mIndex);
			}
			if (size > 0) {
				mIndex = (mIndex + 1) % size;
			}
			notityCallback("getCurrentData", null);
			return data;
		}

		@Override
		public List<EntityData> getDatas() throws RemoteException {
			Log.i(TAG, "getDatas");
			notityCallback("getDatas", null);
			return mDatas;
		}

		@Override
		public void registerCallback(ICallback callback) throws RemoteException {
			Log.i(TAG, "registerCallback");
			mCallback = callback;

			notityCallback("registerCallback", null);
		}

		void notityCallback(String action, Bundle bundle) throws RemoteException {
			if (mCallback != null) {
				mCallback.notify(action, bundle);
			}
		}

	}

}

可以看到服务关键在于onBind方法,此方法继承自一个IBinder,这里的IBinder即为上文提到的IService.aidl文件产生的stub。

IServiceImpl类实现IService.Stub,实现IService.aidl文件中所注明的方法,里面有一个registerCallback方法,参数为aidl文件产生的接口,此方法用于获取客户端的IBinder,然后用于服务端通知客户端,而其他方法则相反,客户端获取服务端的数据。


代码链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值