5

リモート サービスを定義し、サード パーティの開発者に AIDL インターフェイスを提供するプラグインを作成しています。

このリモート サービスを使用して、異なるクライアントの同時要求を処理するにはどうすればよいですか?

それはサービス apk のアクティビティが各クライアントのステータスを保持できるということです。それらが相互に切り替わったとき、どうすればよいですか?

4

2 に答える 2

13

これは、100 個のアプリケーションから受信したすべてのリクエストを保持および処理する Looper で HandlerThread を使用して実現できます。

この AIDL コールバック インターフェースも追加する必要があります。これは、これらのコールバックを介してリクエストが提供されるためです。

サーバーアプリ

IAidlService.aidl

interface IAidlService {
    void getStockInfo(IAidlCallback callback);
}

IAidlCallback.aidl

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

ストックエイドル

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

これは、AIDL Service メソッドをオーバーライドして実装するメインの Service クラスです。また、リクエストを要求している特定のアプリケーションへの出力とともに、リクエストのリターンも処理しました。

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;
        }
    }
}
}

クライアントアプリ

任意のクライアント アプリで を作成し、ServiceConnectionサービスにバインドしたら、'IAidlCallback` のスタブ クラスを作成し、getStockInfo呼び出しと共にオブジェクトを送信するだけです。お気に入り:

IAidlCallback.Stub callback = new IAidlCallback.Stub() {
    @Override
    public void handleStockInfo(Stock stockinfo) throws RemoteException {

        // do what ever you want with stock info :)
    }
};

それが役に立てば幸い :)

于 2015-12-11T06:07:56.633 に答える
0

マルチスレッドサーバーの作成と大差ありません。各クライアントのスレッド ローカル状態を保持し、何らかのセッション ID を与えることで、誰と話しているかがわかります。

于 2012-12-19T09:21:14.430 に答える