ここに新しい Android プログラマーがいます。ソケット管理と非同期 I/O を実行するサービスがあり、それとアプリ内のアクティビティとの間の通信パスを確立する必要があります。
現在のアプローチは、サービスとアクティビティの両方に BroadcastReceivers を装備し、それらを使用してアクティビティからサービスに「コマンド」インテントを送信し、サービスからアクティビティに「アラート」インテントを送信することです。
私のサービスには、ソケットの read() が発生する実行可能ファイルがあります。データが受信されると、ランナブルは「着信データ」インテントをサービスに送信し、サービスはアクティビティに警告します。
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (m_IsRunning == false) {
m_IsRunning = true;
(new Thread(new Runnable() {
byte[] inputBuffer = new byte[512];
public void run() {
while (m_IsRunning) {
if (m_IsConnected) {
try {
m_Nis = m_Socket.getInputStream();
m_Nis.read(inputBuffer, 0, 512);
Intent broadcast = new Intent();
Bundle bun = new Bundle();
bun.putString("ServiceCmd", "ALERT_INCOMING_DATA");
bun.putByteArray("MsgBuffer", inputBuffer);
broadcast.putExtras(bun);
broadcast.setAction(BROADCAST_TO_SERVICE);
sendBroadcast(broadcast);
} catch (IOException e) {
// Send fault to activity
}
}
}
}
})).start();
}
return START_STICKY;
}
BroadcastReceiver を使用した私のアプローチは次のようになります。
private BroadcastReceiver serviceReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bun = intent.getExtras();
String cmdString = bun.getString("ServiceCmd");
if (cmdString.equals("CMD_SETHOSTINFO")) {
// The activity has requested us to set the host info
String hostAddr = bun.getString("HostAddressString");
int hostPort = bun.getInt("HostPortNumber");
processSetHostInfoCommand(hostAddr, hostPort);
}
else if (cmdString.equals("CMD_CONNECT")) {
// The activity has requested us to connect
if ((m_IsRunning) && (m_IsConnected == false)) {
// Attempt to connect
processConnectCommand();
}
}
else if (cmdString.equals("CMD_DISCONNECT")) {
// The activity has requested us to disconnect
if ((m_IsRunning) && (m_IsConnected == true)) {
// Attempt to disconnect
processDisconnectCommand();
}
}
else if (cmdString.equals("CMD_SENDDATA")) {
// The activity has requested us to send data
if ((m_IsRunning) && (m_IsConnected == true)) {
// Attempt to send data
byte[] msgBuffer = bun.getByteArray("MsgBuffer");
processSendDataCommand(msgBuffer);
}
}
else if (cmdString.equals("ALERT_INCOMING_DATA")) {
// Our TCP receiver thread has received data
if (m_IsRunning) {
byte[] msgBuffer = bun.getByteArray("MsgBuffer");
processIncomingDataAlert(msgBuffer);
}
}
}
};
(これらのprocessWhatever()
メソッドは一般に、ソケット管理とデータ転送を行います。)
私が言ったように、それはうまくいくように見えますが、これはメッセージとハンドラーを使用することがより適切ではない場合ではないかと思います.
したがって、具体的な質問は次のとおりです。
BroadcastReceiver/IntentsまたはHandler/Messagesをいつ使用するかを決定する際の「Androidのタオ」は何ですか?
どのアプローチを使用するかを決定する際に、クロススレッドに関する考慮事項はありますか?
(そして、それはトピックから外れていますが、最後の質問です):
- Service は、私が行おうとしている種類のソケットベースの I/O を実行するのに適していますか?