AIDL代码举例
- 补充IPC机制学习中AIDL使用的实例代码。学习笔记正文
- 实现的是客户端与服务端之间的跨进程通信及RPC调用,还有服务端对客户端的定时通知。
1.对象类及AIDL文件
Person.java
public class Person implements Parcelable { public String pName; public int pAge; public Person(String pName, int pAge) { this.pName = pName; this.pAge = pAge; } protected Person(Parcel in) { pName = in.readString(); pAge = in.readInt(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(pName); dest.writeInt(pAge); } @Override public int describeContents() { return 0; } public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person createFromParcel(Parcel in) { return new Person(in); } @Override public Person[] newArray(int size) { return new Person[size]; } }; }
Person.aidl
// Person.aidl package com.virtual.aidltest; //Person类在AIDL中的声明 parcelable Person;
IPersonManager.aidl
// IPersonManager.aidl package com.virtual.aidltest; import com.virtual.aidltest.Person; import com.virtual.aidltest.IOnNewPersonArrivedListener; interface IPersonManager { List<Person> getPersonList(); void addPerson(in Person person); void registerListener(IOnNewPersonArrivedListener listener); void unregisterListener(IOnNewPersonArrivedListener listener); }
IOnNewBookArrivedListener.aidl
// IOnNewBookArrivedListener.aidl package com.virtual.aidltest; import com.virtual.aidltest.Person; interface IOnNewPersonArrivedListener { void onNewPersonArrived(in Person newPerson); }
2.服务端
PersonManagerService.java
public class PersonManagerService extends Service { private static final String TAG = "PersonManagerService"; /** * 并发情况下使用AtomicBoolean */ private AtomicBoolean mIsServiceDestroyed = new AtomicBoolean(false); /** * 1.AIDL方法是在服务端的Binder线程池中执行的,多客户端同时连接时,会存在多线程同时访问的情况。 * 2.CopyOnWriteArrayList支持并发读/写。 * 3.我们要在AIDL方法中处理线程同步,可以使用CopyOnWriteArrayList进行自动线程同步。 */ private CopyOnWriteArrayList<Person> mPersonList = new CopyOnWriteArrayList<>(); /** * RemoteCallbackList是系统专门提供用于删除跨进程listener的接口。 */ private RemoteCallbackList<IOnNewPersonArrivedListener> mListenerList = new RemoteCallbackList<>(); private Binder mBinder = new IPersonManager.Stub() { @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { int check = checkCallingOrSelfPermission("com.virtual.aidltest.ACCESS_PERSON_SERVICE"); if (check == PackageManager.PERMISSION_DENIED) { return false; } String packageName = null; String[] packages = getPackageManager().getPackagesForUid(getCallingUid()); if (packages != null && packages.length > 0) { packageName = packages[0]; } if (!packageName.startsWith("com.virtual")) { return false; } return super.onTransact(code, data, reply, flags); } @Override public List<Person> getPersonList() throws RemoteException { return mPersonList; } @Override public void addPerson(Person person) throws RemoteException { mPersonList.add(person); } @Override public void registerListener(IOnNewPersonArrivedListener listener) throws RemoteException { mListenerList.register(listener); } @Override public void unregisterListener(IOnNewPersonArrivedListener listener) throws RemoteException { mListenerList.unregister(listener); } }; @Override public void onCreate() { super.onCreate(); //先添加两个人员对象 mPersonList.add(new Person("Tim", 31)); mPersonList.add(new Person("Jack", 11)); /** * 每隔5s添加一个新用户,并通知所有绑定的客户端 */ new Thread(new ServiceWorker()).start(); } @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onDestroy() { mIsServiceDestroyed.set(true); super.onDestroy(); } private class ServiceWorker implements Runnable { @Override public void run() { while (!mIsServiceDestroyed.get()) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } Person newPerson = new Person("Kim", 11); try { onNewPersonArrived(newPerson); } catch (RemoteException e) { e.printStackTrace(); } } } } private void onNewPersonArrived(Person person) throws RemoteException { mPersonList.add(person); final int N = mListenerList.beginBroadcast(); Log.d(TAG, "onNewPersonArrived, notify listeners: " + N); for (int i = 0; i < N; i++) { IOnNewPersonArrivedListener listener = mListenerList.getBroadcastItem(i); Log.d(TAG, "onNewPersonArrived, notify listener: " + listener); listener.onNewPersonArrived(person); } //与beginBroadcast匹配对应 mListenerList.finishBroadcast(); } }
3.客户端
PersonManagerActivity.java
public class PersonManagerActivity extends AppCompatActivity { private static final String TAG = "PersonManagerActivity"; private static final int MESSAGE_NEW_PERSON_ARRIVED = 1; private IPersonManager mRemotePersonManager; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_NEW_PERSON_ARRIVED: Log.d(TAG, "receive new person: " + msg.obj); break; default: super.handleMessage(msg); } } }; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IPersonManager personManager = IPersonManager.Stub.asInterface(service); try { //查找 mRemotePersonManager=personManager; List<Person> lsit = personManager.getPersonList(); Log.d(TAG, "querry person list, list type: " + lsit.getClass()); Log.d(TAG, "querry person list: " + lsit.get(0).pName); //添加 Person newPerson = new Person("Kit", 16); personManager.addPerson(newPerson); Log.d(TAG, "add new person! "+newPerson); //再次查看 List<Person> newLsit = personManager.getPersonList(); Log.d(TAG, "querry person list 2nd, list type: " + lsit.getClass()); personManager.registerListener(mOnNewPersonArrivedListener); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { mRemotePersonManager=null; Log.d(TAG, "binder died!"); } }; private IOnNewPersonArrivedListener mOnNewPersonArrivedListener = new IOnNewPersonArrivedListener.Stub() { @Override public void onNewPersonArrived(Person newPerson) throws RemoteException { mHandler.obtainMessage(MESSAGE_NEW_PERSON_ARRIVED,newPerson).sendToTarget(); } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_messenger); Intent intent = new Intent(this, PersonManagerService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { if(mRemotePersonManager!=null && mRemotePersonManager.asBinder().isBinderAlive()){ try { Log.d(TAG, "unregister listener: "+mOnNewPersonArrivedListener); mRemotePersonManager.unregisterListener(mOnNewPersonArrivedListener); } catch (RemoteException e) { e.printStackTrace(); } } unbindService(mConnection); super.onDestroy(); } }
4.AndroidManifest
服务端注册:
<service android:name=".PersonManagerService" android:enabled="true" android:exported="true" android:process=":remote"/>
客户端注册:
<activity android:name=".PersonManagerActivity"/>