aidl复杂流程封装

1 aidl相关困扰点


1 制作步骤复杂,先定义然后编译,然后复制,两边都要一一对应
2 增加回调,自定义对象流程更加麻烦,还要处理对象数据流是 in 还是out。
3 一方异常怎么办,虽然服务端可以用 RemoteCallbackList 客户端可以用DeathRecipient来处理,但很麻烦
4 考虑服务端一对多时候,需要一对一发送消息
很累很麻烦,使用还不方便,所以我必须设计一个aar包,将这些细节全都封进去,以后再也不关心这些破玩意了

2 解决方案

1 为了应对各种对象,统一转为string进行传输(可通过json等转成对应的对象)
2 通过添加封装类对 aidl的连接流程进行封装,本地的也封装以下(虽然本地的bind可以直接进程内通信)
3 传输监听对象时,需要传输一个唯一值 ,通过map保存该唯一值。这样就可以通过key值进行针对性传输,也可以找到该监听类,不再通过RemoteCallbackList来移除监听类了。

4 提供异步和同步访问,因为有些操作同步会导致 service 卡顿(四大组件之一的服务是运行在主线程),所以是需要提供下异步操作的。

3 实现

接下来看下大概的类图吧,然后下一步就是具体的实现了。

aidl复杂流程封装_第1张图片

先来看下本地服务类代码:
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 LinkedBlockingQueue msgLBQ = 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 HashMap mCallbacksMap = 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类

你可能感兴趣的:(常用知识点分类汇总,android)