How can I use AIDL remote service to deal with defferent clients' concurrent requests?

前端 未结 2 1362
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-19 10:29

I\'m writting a plug-in which defines a remote Service and provides a AIDL interface for 3rd party developers.

How can I use this remote service to deal with deffer

相关标签:
2条回答
  • 2020-12-19 11:03

    This can be achieved using HandlerThread with Looper which maintains and service all the request no matter received from 100 applications.

    For this AIDL callback interface is also needs to be added as request will be furnished through these callbacks.

    SERVER APP

    IAidlService.aidl

    interface IAidlService {
        void getStockInfo(IAidlCallback callback);
    }
    

    IAidlCallback.aidl

    oneway interface IAidlCallback {
        void handleStockInfo(in Stock stockinfo);
    }
    

    Stock.aidl

    parcelable Stock;
    

    Stock.java

    public class Stock implements Parcelable {
    
    String stockName;
    
    public String getStockName() {
        return stockName;
    }
    
    public void setStockName(String stockName) {
        this.stockName = stockName;
    }
    
    @Override
    public int describeContents() {
        return 0;
    }
    
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(stockName);
    }
    
    public static final Creator<Stock> CREATOR = new Parcelable.Creator<Stock>() {
        @Override
        public Stock createFromParcel(Parcel in) {
            return new Stock(in);
        }
    
        @Override
        public Stock[] newArray(int size) {
            return new Stock[size];
        }
    };
    
    public Stock(Parcel in) {
        this.stockName = in.readString();
    }
    
    public Stock() {}
    }
    

    AidlService.java

    This is main Service class which overrides the AIDL Service methods and implements them. It also handled the return of request with output to specific application requesting for it.

    public class AidlService extends Service {
    
    private static final int MSG_STOCK_INFO = 53;
    
    private ArrayList<IAidlCallback> mRemoteCallbacks;
    
    private ServiceHandler mHandler = null;
    
    HandlerThread mHandlerThread = new HandlerThread("AidlServiceThread");
    
    @Override
    public void onCreate() {
        super.onCreate();
    
        mRemoteCallbacks = new ArrayList<>();
    }
    
    @Override
    public IBinder onBind(Intent intent) {
    
        // Handler Thread handling all call back methods
        mHandlerThread.start();
        mHandler = new ServiceHandler(mHandlerThread.getLooper());
    
        return mBinder;
    }
    
    /**
     * Stub implementation for Remote service
     */
    IAidlService.Stub mBinder = new IAidlService.Stub() {
    
        @Override
        public void getStockInfo(IAidlCallback callback) throws RemoteException {
    
            sendMsgToHandler(callback, MSG_STOCK_INFO);
        }
    };
    
    /**
     * Create handler message to be sent
     *
     * @param callback
     * @param flag
     */
    void sendMsgToHandler(IAidlCallback callback, int flag) {
    
        mRemoteCallbacks.add(callback);
    
        Message message = mHandler.obtainMessage();
        message.arg1 = mRemoteCallbacks.size() - 1;
    
        message.what = flag;
        mHandler.sendMessage(message);
    }
    
    /**
     * Handler class sending result in callback to respective
     * application
     */
    private class ServiceHandler extends Handler {
        int callbackIndex = 0;
    
        ServiceHandler(Looper looper) {
            super(looper);
        }
    
        @Override
        public void handleMessage(Message msg) {
            callbackIndex = msg.arg1;
    
            switch (msg.what) {
    
                case MSG_STOCK_INFO:
    
                    Stock stock = new Stock();
                    stock.setStockName("Apple Inc");
    
                    try {
                        mRemoteCallbacks.get(callbackIndex).handleStockInfo(stock);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
            }
        }
    }
    }
    

    CLIENT APP

    In any client app create a ServiceConnection and once binded to service you simply need to make Stub class for 'IAidlCallback` and send object along with getStockInfo call. Like:

    IAidlCallback.Stub callback = new IAidlCallback.Stub() {
        @Override
        public void handleStockInfo(Stock stockinfo) throws RemoteException {
    
            // do what ever you want with stock info :)
        }
    };
    

    Hope it helps :)

    0 讨论(0)
  • 2020-12-19 11:19

    Not much different than writing a multi-threaded server. You keep thread local state for each client, and maybe give them some sort of session ID so you know who you are talking to.

    0 讨论(0)
提交回复
热议问题