为了确保我写的服务在需要的时候一直运行在后台,我用到了守护进程机制,但是这样又出现了新的问题:两个进程不能调用同一个实例。
1、创建AIDL文件
通过写测试程序,aidl文件所在的包名可以与AndroidMainifest.xml文件的package名不一致
在IServiceAidlInterface.aidl文件中我定义了三个方法:
// IServiceAidlInterface.aidl package com.yjn.cyclingworld; // Declare any non-default types here with import statements import java.util.List; import com.yjn.cyclingworld.bean.CyclingData; import com.yjn.cyclingworld.AIDLCallBack; interface IServiceAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ List<CyclingData> getCyclingData(); void registerClient(AIDLCallBack cb); void unregisterClient(); }
其中getCyclingData()方法是获取自定义的CyclingData类的对象,所以必须导入该类的aidl文件。而CyclingData.java文件早就在java文件夹下的com.yjn.cyclingworld.bean包创建好了,所以CyclingData.aidl文件也创建在aidl文件夹中相同的包名下。还有两个方法是实现对客户端的调用。
// CyclingData.aidl package com.yjn.cyclingworld.bean; // Declare any non-default types here with import statements //import com.yjn.cyclingworld.bean.CyclingData; parcelable CyclingData;
跨进程通信传输的自定义的类必须先序列化,我把CyclingData.java类实现了Parcelable接口,在CyclingData.aidl文件中还需要声明parcelable CyclingData。
2、在Service类中实现AIDL接口
private final IBinder lib = new IServiceAidlInterface.Stub() { @Override public List<CyclingData> getCyclingData() throws RemoteException { return mCyclingDatas; } @Override public void registerClient(AIDLCallBack cb) throws RemoteException { LogUtil.e(TAG,"registerClient"); client = cb; } @Override public void unregisterClient() throws RemoteException { LogUtil.e(TAG,"unregisterClient"); client = null; } };
3、在需要与Service通信的类中实现ServiceConnection接口,就可以使用IServiceAidlInterface.aidl文件里定义的接口了
private class ServiceConnect implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { mCyclingWorldService = IServiceAidlInterface.Stub.asInterface(service); try { mCyclingWorldService.registerClient(cb); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { mCyclingWorldService = null; } }