一.完成文件的AIDL创建,这里采用单独打成jar包的形式:
关键代码在ServiceManage中:
package com.example.testaidl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import java.util.concurrent.CountDownLatch;
public class ServiceManage {
private static final String TAG = "ServiceManage";
private Context mContext;
private IBinderPool mBinderPoolImpl;
private static volatile ServiceManage sInstance;
private CountDownLatch mConnectBinderPoolCountDownLatch;
private final String packName = "com.example.testmyaidl";
private final String ctlName = "com.example.testmyaidl.MyService";
private boolean mServiceConnected;
private boolean mServiceBound;
private static final int MSG_RETRY_BIND_SERVICE = 0;
private static final Object LOCK = new byte[1];
private static final int MAX_RETRY_COUNT = 3;
private int mRetryTimes = 0;
private HandlerThread mRetryHandlerThread;
private static final String RETRY = "retry_thread";
private RetryHandler mRetryHandler;
private static final int TIME_RETRY_BIND_SERVICE = 1000;
private class RetryHandler extends Handler {
private RetryHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_RETRY_BIND_SERVICE) {
synchronized (LOCK) {
if (mRetryTimes < MAX_RETRY_COUNT) {
rebindService();
mRetryTimes++;
}
}
} /*else {
// other what, do nothing...
}*/
}
}
private ServiceManage(Context context) {
mContext = context;
if (mRetryHandlerThread == null) {
mRetryHandlerThread = new HandlerThread(RETRY) {
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mRetryHandler = new RetryHandler(mRetryHandlerThread.getLooper());
}
};
mRetryHandlerThread.start();
}
if (mRetryHandler == null) {
mRetryHandler = new RetryHandler(mRetryHandlerThread.getLooper());
}
connectBinderPoolService();
}
public static ServiceManage getInstance(Context context) {
if (sInstance == null) {
synchronized (ServiceManage.class) {
if (sInstance == null) {
sInstance = new ServiceManage(context);
}
}
}
return sInstance;
}
/**
* 连接binder,并且等到onServiceConnected结束执行完
*/
private synchronized void connectBinderPoolService() {
mConnectBinderPoolCountDownLatch = new CountDownLatch(1);
Intent intent = new Intent();
ComponentName name = new ComponentName(packName, ctlName);
intent.setComponent(name);
intent.setAction("start_AIDL_service");
mServiceBound = mContext.bindService(intent, mBinderPoolConnection, Context.BIND_AUTO_CREATE);
//重连三次
try {
// 当前线程进入等待,直到主线程onServiceConnected执行完毕,则该线程唤醒
mConnectBinderPoolCountDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (LOCK) {
if (!mServiceBound && mRetryTimes < MAX_RETRY_COUNT) {
if (mRetryHandler.hasMessages(MSG_RETRY_BIND_SERVICE)) {
mRetryHandler.removeMessages(MSG_RETRY_BIND_SERVICE);
}
mRetryHandler.sendEmptyMessageDelayed(MSG_RETRY_BIND_SERVICE, TIME_RETRY_BIND_SERVICE);
}
}
}
/**
* 返回对应的binder
* @param binderCode binderCode
* @return
*/
public IBinder queryBinder(int binderCode) {
IBinder binder = null;
try {
if (mBinderPoolImpl != null) {
binder = mBinderPoolImpl.queryBinder(binderCode);
}
} catch (RemoteException e) {
e.printStackTrace();
}
return binder;
}
private ServiceConnection mBinderPoolConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBinderPoolImpl = IBinderPool.Stub.asInterface(service);
try {
mBinderPoolImpl.asBinder().linkToDeath(mBinderPoolDeathRecipient, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
// 计数减1,当计数为0时唤醒被它阻塞的线程
mConnectBinderPoolCountDownLatch.countDown();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mConnectBinderPoolCountDownLatch.countDown();
mServiceConnected = false;
}
};
private IBinder.DeathRecipient mBinderPoolDeathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
Log.d(TAG, "binderDied: ");
mBinderPoolImpl.asBinder().unlinkToDeath(mBinderPoolDeathRecipient, 0);
mBinderPoolImpl = null;
connectBinderPoolService();
}
};
/**
* 重连服务
*/
protected void rebindService() {
if (!mServiceConnected) {
connectBinderPoolService();
}
}
/**
* 断开服务
*/
public void unbindService() {
Log.d(TAG, "unbindService:) ");
if (mServiceConnected && mServiceBound) {
mContext.unbindService(mBinderPoolConnection);
mServiceConnected = false;
mServiceBound = false;
}
if (mRetryHandler != null) {
mRetryHandler.removeCallbacksAndMessages(null);
}
if (mRetryHandlerThread != null) {
mRetryHandlerThread.quitSafely();
}
}
}
注意事项:1.这个moudle下,build.gradle需要:
sourceSets {
main {
manifest.srcFile ‘src/main/AndroidManifest.xml’
java.srcDirs = [‘src/main/java’, ‘src/main/aidl’]
resources.srcDirs = [‘src/main/java’, ‘src/main/aidl’]
aidl.srcDirs = [‘src/main/aidl’]
res.srcDirs = [‘src/main/res’]
assets.srcDirs = [‘src/main/assets’]
}
}
2.实体类Message需要对应的Message.aidl
二、服务端引入jar,构建之后,实现aidl接口:
关键代码:
binder连接池:
package com.example.testmyaidl;
import android.os.IBinder;
import android.os.RemoteException;
import com.example.testaidl.IBinderPool;
public class IBinderPoolImp extends IBinderPool.Stub {
public static final int BINDER_PERSON = 0;
public static final int BINDER_MESSAGE = 1;
private IBinder iBinder = new IMessageManageImp();
private IBinder mBinder = new IPersonImp();
@Override
public IBinder queryBinder(int binderCode) throws RemoteException {
IBinder binder = null;
switch (binderCode){
case BINDER_MESSAGE:
binder = iBinder;
break;
case BINDER_PERSON:
binder = mBinder;
break;
default:break;
}
return binder;
}
}
2.在实现类中使用RemoteCallbackList,通知每个客户端数据的变化:
package com.example.testmyaidl;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import com.example.testaidl.IMessage;
import com.example.testaidl.IMsgAidlInterface;
import com.example.testaidl.Message;
import java.util.List;
public class IMessageManageImp extends IMessage.Stub {
private final String TAG = IMessageManageImp.class.getSimpleName();
private RemoteCallbackList<IMsgAidlInterface> mRemoteCallbackList = new RemoteCallbackList<>();
@Override
public List<Message> getMsgList() throws RemoteException {
return null;
}
@Override
public void addMsg(Message message) throws RemoteException {
Log.i(TAG, "addMsg: "+message.toString());
int count = mRemoteCallbackList.beginBroadcast();
//这块用于通知多个client
Log.i(TAG, "count: "+count);
if (count > 0) {
for (int i = 0; i < count; i++) {
mRemoteCallbackList.getBroadcastItem(i).onNewMsgArrived(message);
}
mRemoteCallbackList.finishBroadcast();
}
}
@Override
public void registerListener(IMsgAidlInterface listener) throws RemoteException {
if (null != mRemoteCallbackList) {
mRemoteCallbackList.register(listener);
}
}
@Override
public void unregisterListener(IMsgAidlInterface listener) throws RemoteException {
if (null == mRemoteCallbackList) {
return;
}
mRemoteCallbackList.unregister(listener);
}
}
三、客户端
使用ServiceManage完成绑定服务,和调用对应的方法
package com.example.client;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.testaidl.IMessage;
import com.example.testaidl.IMsgAidlInterface;
import com.example.testaidl.IPerson;
import com.example.testaidl.Message;
import com.example.testaidl.MessageManage;
import com.example.testaidl.ServiceManage;
public class MainActivity extends AppCompatActivity {
private String packName = "com.example.testmyaidl";
private String ctlName = "com.example.testmyaidl.MyService";
private IMessage iMessageManage;
private TextView textView;
private Button button;
private final String TAG = MainActivity.class.getSimpleName();
private MessageManage messageManage;
private IMsgAidlInterface.Stub iMsgAidlInterface = new IMsgAidlInterface.Stub() {
@Override
public void onNewMsgArrived(Message newMusic) throws RemoteException {
Log.e(TAG, "onNewMsgArrived: 收到了" +newMusic.toString());
}
};
private ServiceManage serviceManage;
private String name = "" ;
IPerson iPerson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
serviceManage = ServiceManage.getInstance(getApplicationContext());
iPerson = IPerson.Stub.asInterface(serviceManage.queryBinder(0));
try {
iPerson.setName("xiong");
name = iPerson.getName();
} catch (RemoteException e) {
e.printStackTrace();
}
IMessage iMessage = IMessage.Stub.asInterface(serviceManage.queryBinder(1));
try {
iMessage.registerListener(new IMsgAidlInterface.Stub() {
@Override
public void onNewMsgArrived(Message newMusic) throws RemoteException {
Log.e(TAG, "onNewMsgArrived: 收到了" +newMusic.toString());
}
});
iMessage.addMsg(new Message(1,"xiong"));
} catch (RemoteException e) {
e.printStackTrace();
}
}
}).start();
textView = findViewById(R.id.test_AIDL_text);
button = findViewById(R.id.button_bind);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG, "onClick: ");
textView.setText(name);
}
});
}
}
整个结果就完成了。