У меня есть класс Service, который связывается с моим другим процессом, скажем, process_A, локальным сокетом.Ошибка чтения и записи Android FileChannel в разных AsyncTask
классаМоей службы выглядит следующим образом:
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 процессу_A и дождаться сообщения INIT от process_A.
- Когда моя служба останавливается пользователем, служба выполняет другую AsyncTask, чтобы отправить сообщение TERM процессу_A и дождаться сообщения TERM от process_A.
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 выполняется отлично, как запись, так и чтение успешны. Однако при выполнении второй AsyncTask (которая является LocalSockTermTask) кажется, что запись и чтение не увенчались успехом. Я сделал некоторые испытания на этой линии:
inChannel.read(recvBuf);
В исполнении первой AsyncTask (LocalSockInitTask), если ничего не может быть прочитан, этот метод немедленно возвращает -1, и именно поэтому я установил время цикла и посчитать попытка.
Во втором выполнении AsyncTask (LocalSockTermTask), если ничего не может быть прочитано, этот метод будет заблокирован, и это сделает мой цикл while и попытку попыткой стать бесполезной. Это приведет к тому, что AsyncTask никогда не завершится. Кроме того, My process_A ждет завершения «MSG_TERM», и он остается запущенным, поэтому я думаю, что outChannel.write (sendBuf) также потерпел неудачу в задаче Term.
В настоящее время я передаю объект LocalSocket как AsyncTask, так и создаю пару в/из FileChannel в AsyncTask. Я также попытался создать пару in/out FileChannel в службе и передать два FileChannel в AsyncTask, но по-прежнему сталкивается с той же проблемой.
Любая помощь очень ценится!