Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
462 views
in Technique[技术] by (71.8m points)

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

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 defferent clients' concurrent requests?

It is that service apk's activitys can keep status for each client, when they switched between each other, how to do it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...