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