簡體   English   中英

Android FileChannel讀取和寫入在不同的AsyncTask中失敗

[英]Android FileChannel read & write fails in different AsyncTask

我有一個Service類,通過本地套接字與我的另一個進程通信,比如說process_A。

我的服務類如下:

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

行為應如下:

  1. 當用戶啟動我的服務時,該服務使用LocalSocket.connect()連接process_A。 成功連接后,服務執行AsyncTask以向process_A發送INIT消息並等待來自process_A的INIT消息。
  2. 當我的服務被用戶停止時,該服務執行另一個AsyncTask以向Process_A發送TERM消息並等待來自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任務完美無缺,寫入和讀取都是成功的。 但是,當執行第二個AsyncTask(即LocalSockTermTask)時,寫入和讀取似乎都不成功。 我在這條線上做了一些測試:

inChannel.read(recvBuf);

在第一個AsyncTask執行(LocalSockInitTask)中,如果無法讀取任何內容,此方法將立即返回-1,這就是我設置while循環並計算嘗試次數的原因。

在第二個AsyncTask執行(LocalSockTermTask)中,如果無法讀取任何內容,則此方法將被阻止,這使得我的while循環和嘗試計數變得無用。 這導致AsyncTask永遠不會完成。 此外,我的process_A正在等待“MSG_TERM”終止,並且它仍然在運行,這就是為什么我認為outChannel.write(sendBuf)在Term任務中也失敗了。

目前我將LocalSocket對象傳遞給AsyncTask並在AsyncTask中創建一對輸入/輸出FileChannel。 我還嘗試在服務中創建一對輸入/輸出FileChannel,並將兩個FileChannel傳遞給AsyncTask,但仍面臨同樣的問題。

任何幫助是極大的贊賞!

好的,我發現這是我粗心的錯誤。 問題已經解決了。

  1. 我的另一個進程錯誤地處理了TERM消息,因此它只是忽略了我的AsyncTask發送的TERM消息,因此它繼續運行並等待消息。

  2. 由於它忽略了TERM消息,因此它不會向我的AsyncTask發回TERM消息,這導致inChannel.read(recvBuf)無法讀取。

  3. inChannel.read(recvBuf)的阻塞行為是絕對正常的,返回-1應該是我在更改為使用FileChannel之前使用BufferedReader的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM