私は別のプロセスと通信するServiceクラスを持っています。これはローカルソケットによってprocess_Aと言いましょう。別のAsyncTaskでAndroid FileChannelの読み込みと書き込みが失敗する
次のように私のサービスクラスがある:次のように
public class MyService extends Service {
private LocalSocket localSock;
private LocalSocketAddress localSockAddr;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(START_SERVICE_ACTION)) {
localSock = new LocalSocket();
localSockAddr = new LocalSocketAddress(LOCAL_SOCK_ADDR, LocalSocketAddress.Namespace.ABSTRACT);
try {
localSock.connect(localSockAddr);
} catch (IOException e) {
// Ignore
}
if (localSock.isConnected()) {
new LocalSockInitTask().execute(localSock);
}
} else if (intent.getAction().equals(STOP_SERVICE_ACTION)) {
new LocalSockTermTask().execute(localSock);
}
}
}
動作は次のようになります。
- 私のサービスは、ユーザーによって開始されている場合は、サービスが接続するためのLocalSocket.connect()を使用していますprocess_Aで接続に成功すると、サービスはAsyncTaskを実行してINITメッセージをprocess_Aに送信し、process_AからのINITメッセージを待機します。
- サービスがユーザーによって停止されている場合、サービスは別のAsyncTaskを実行してTERMメッセージをprocess_Aに送信し、process_AからのTERMメッセージを待機します。
LocalSockInitTask.java:
public class LocalSockInitTask extends AsyncTask<LocalSocket, Void, Boolean> {
@Override
protected Boolean doInBackground(LocalSocket... params) {
LocalSocket localSock = params[0];
FileChannel inChannel;
FileChannel outChannel;
ByteBuffer sendBuf, recvBuf;
byte[] bytes;
String result, recvMsg;
int attempt;
try {
inChannel = new FileInputStream(localSock.getFileDescriptor()).getChannel();
outChannel = new FileOutputStream(localSock.getFileDescriptor()).getChannel();
// Send INIT Message
sendBuf = ByteBuffer.wrap(MSG_INIT.getBytes());
outChannel.write(sendBuf);
// Wait for INIT Message
recvBuf = ByteBuffer.allocate(BUFFER_SIZE);
attempt = 0;
while (inChannel.read(recvBuf) < 0) {
attempt++;
if(attempt == 5)
return false;
Thread.sleep(1000);
}
recvBuf.flip();
bytes = new byte[recvBuf.remaining()];
recvBuf.get(bytes);
result = new String(bytes);
if(!result.equals(MSG_INIT))
return false;
inChannel.close();
outChannel.close();
return true;
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
}
LocalSockTermTask.javaはほぼLocalSockInitTask.javaと同じようにやっている、主な違いは、単にメッセージの送受信であることは "MSG_TERM" です。
Initタスクが完全に実行されています。書き込みと読み取りの両方が成功しています。しかし、2番目のAsyncTask(LocalSockTermTask)を実行すると、書き込みと読み取りの両方がうまくいかないようです。 Iこのライン上のいくつかのテストをやった:何も読むことができない場合、最初のAsyncTaskの実行(LocalSockInitTask)で
inChannel.read(recvBuf);
を、このメソッドはすぐに戻ります-1と私はwhileループを設定する理由ですとカウント試みる。
2回目のAsyncTask実行(LocalSockTermTask)では、何も読み込めない場合、このメソッドはブロックされ、これによりwhileループと試行回数が無駄になります。これにより、AsyncTaskは決して完了しません。また、私のprocess_Aは "MSG_TERM"が終了するのを待っていて、実行中のままです。そのため、outChannel.write(sendBuf)もTermタスクで失敗したと思います。
現在、私はLocalSocketオブジェクトをAsyncTaskに渡して、AsyncTaskにin/out FileChannelのペアを作成しています。また、サービス内にIn/Out FileChannelのペアを作成し、AsyncTaskに2つのFileChannelを渡しましたが、同じ問題に直面していました。
ご協力いただきありがとうございます。