1 制作步骤复杂,先定义然后编译,然后复制,两边都要一一对应
2 增加回调,自定义对象流程更加麻烦,还要处理对象数据流是 in 还是out。
3 一方异常怎么办,虽然服务端可以用 RemoteCallbackList 客户端可以用DeathRecipient来处理,但很麻烦
4 考虑服务端一对多时候,需要一对一发送消息
很累很麻烦,使用还不方便,所以我必须设计一个aar包,将这些细节全都封进去,以后再也不关心这些破玩意了
1 为了应对各种对象,统一转为string进行传输(可通过json等转成对应的对象)
2 通过添加封装类对 aidl的连接流程进行封装,本地的也封装以下(虽然本地的bind可以直接进程内通信)
3 传输监听对象时,需要传输一个唯一值 ,通过map保存该唯一值。这样就可以通过key值进行针对性传输,也可以找到该监听类,不再通过RemoteCallbackList来移除监听类了。
4 提供异步和同步访问,因为有些操作同步会导致 service 卡顿(四大组件之一的服务是运行在主线程),所以是需要提供下异步操作的。
接下来看下大概的类图吧,然后下一步就是具体的实现了。
先来看下本地服务类代码: public abstract class AsynService extends Service { protected static final String TAG = "JsonProtocolService"; protected WorkThread worker; public void onCreate() { super.onCreate(); if (this.worker == null || !this.worker.isRunning()) { this.worker = new WorkThread(); this.worker.start(); } } public void onDestroy() { super.onDestroy(); if (this.worker != null && this.worker.isRunning()) { this.worker.interrupt(); this.worker = null; } } protected String getRequestAuthor(String params) { String requestAuthor = null; try { JSONObject jsonObject = new JSONObject(params); if (jsonObject.has(SDKConstants.KEY_CLIENT_REQUEST_AUTHOR)) { requestAuthor = jsonObject.optString(SDKConstants.KEY_CLIENT_REQUEST_AUTHOR); } } catch (JSONException e) { Log.e(TAG, "getRequestAuthor: ", e); } return requestAuthor; } protected void offerReq(JsonProtocolManager.Message message) { this.worker.offerReq(message); } //具体实现接口抽象出来给外部实现 public interface ServiceCallback { void onEvent(int event, String msg); void received(String params, Bundle bundle); String receivedSync(String params, Bundle bundle); } protected static class WorkThread extends Thread { private static final Object syncObj = new Object(); private final LinkedBlockingQueuemsgLBQ = new LinkedBlockingQueue<>(); private boolean isRunning = false; private ServiceCallback serviceCallback; public void init(ServiceCallback callback) { synchronized(syncObj) { this.serviceCallback = callback; syncObj.notify(); } } public void onEvent(int event, String msg) { synchronized(syncObj) { if (this.serviceCallback != null) { this.serviceCallback.onEvent(event, msg); } } } public void offerReq(JsonProtocolManager.Message message) { this.msgLBQ.offer(message); } public void run() { this.isRunning = true; while (this.isRunning) { try { JsonProtocolManager.Message msg = this.msgLBQ.take(); synchronized(syncObj) { while (this.serviceCallback == null) { syncObj.wait(); } } if (!this.onReceive(msg)) { this.msgLBQ.offer(msg); } } catch (Exception e) { e.printStackTrace(); } } } boolean isRunning() { return this.isRunning; } private boolean onReceive(JsonProtocolManager.Message message) { synchronized(syncObj) { if (this.serviceCallback != null) { LogUtils.e(TAG, "receive params=" + message.mParams); this.serviceCallback.received(message.mParams, message.mBundle); return true; } else { return false; } } } } protected ServiceCallback mServiceCallback; public void setServiceCallback(ServiceCallback mLocalCallback) { this.mServiceCallback = mLocalCallback; } abstract void send(JsonProtocolManager.Message message); abstract String sendSync(String params, Bundle bundle); //本地bind,进程内通信 public class ServiceBinder extends Binder { public void setServiceCallback(ServiceCallback callback) { AsynService.this.setServiceCallback(callback); AsynService.this.worker.init(callback); } public void send(JsonProtocolManager.Message message) { AsynService.this.send(message); } public String sendSync(String params, Bundle bundle) { return AsynService.this.sendSync(params, bundle); } } }
再来看下 实现类:
public class AidlService extends AsynService { private static final String TAG = "JsonProtocolService"; private final HashMapmCallbacksMap = new HashMap (); private final ServiceBinder localBinder = new ServiceBinder(); private final IServiceBinder.Stub remoterBinder = new IServiceBinder.Stub() { @Override public int register(int versionCode, String caller, ICallback callback) { LogUtils.d(TAG, "register: versionCode = " + versionCode + " , caller = " + caller); mCallbacksMap.put(caller, callback); //remoteCallbackList.register(callback); worker.onEvent(SDKConstants.EVENT_CLIENT_CONNECTED, "client is connected!"); return SDKConstants.VERSION_CODE; } @Override public void received(String params, Bundle bundle) { JsonProtocolManager.Message message = new JsonProtocolManager.Message(params, bundle); offerReq(message); } @Override public String receivedSync(String params, Bundle bundle) { return mServiceCallback == null ? "" : mServiceCallback.receivedSync(params, bundle); } @Override public void unregister(String caller, ICallback callback) { mCallbacksMap.remove(caller); //remoteCallbackList.unregister(callback); worker.onEvent(SDKConstants.EVENT_CLIENT_DISCONNECTED, "client is disconnected!"); } }; @Override public IBinder onBind(Intent intent) { LogUtils.d(TAG, "onBind"); if (intent != null && intent.hasExtra(SDKConstants.CONNECT_EXTRA_KEY)) { String from = intent.getStringExtra(SDKConstants.CONNECT_EXTRA_KEY); if (SDKConstants.CONNECT_EXTRA_VALUE_LOCAL.equals(from)) { LogUtils.d(TAG, "onBind:local"); return this.localBinder; } if (SDKConstants.CONNECT_EXTRA_VALUE_REMOTER.equals(from)) { LogUtils.d(TAG, "onBind:remoter"); return this.remoterBinder; } } return null; } @Override protected void send(JsonProtocolManager.Message message) { try { int N = mCallbacksMap.size(); if (N > 0) { LogUtils.e(TAG, "send params=" + message.mParams); ICallback l = null; String requestAuthor = getRequestAuthor(message.mParams); if (mCallbacksMap.size() > 0 && !TextUtils.isEmpty(requestAuthor)) { l = mCallbacksMap.get(requestAuthor); } if (l != null) { l.received(message.mParams, message.mBundle); }else { Log.e(TAG, "send: client is NOT connected:" + requestAuthor); } } else if (N == 0) { Log.e(TAG, "send: client is NOT connected"); } } catch (Exception e) { LogUtils.e(TAG, "send params=" + message.mParams); } } @Override protected String sendSync(String params, Bundle bundle) { try { int N = mCallbacksMap.size(); if (N > 0) { LogUtils.e(TAG, "send params=" + params); ICallback l = null; String requestAuthor = getRequestAuthor(params); if (mCallbacksMap.size() > 0 && !TextUtils.isEmpty(requestAuthor)) { l = mCallbacksMap.get(requestAuthor); } if (l != null) { return l.receivedSync(params, bundle); } else { Log.e(TAG, "sendSync: client is NOT connected:" + requestAuthor); } } else if (N == 0) { Log.e(TAG, "sendSync: client is NOT connected"); } } catch (Exception e) { LogUtils.e(TAG, "send params=" + params); } return null; } }
下次再来接下来的manager类