0

在我的 android 应用程序中,我有这段代码:

         while(testCase){
            for(HttpPut put : httpPut){
                try {
                    httpclient.execute(put, responseHandler);
                } catch (ClientProtocolException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

我的目标是让一个预先构建的 HTTPPut 请求列表(在本例中为“httpPut”)按顺序每 150 毫秒发送一次,同时在一个永远循环中,直到被告知中断(被“testCase”布尔值中断)。它在技术上有效,但在实际执行中有时会有很多滞后。在每个请求的接收端,它在接收另一个 HTTPPut 之前可能会延迟 3-5 秒。而手机屏幕关闭的情况更糟。我在扩展的 AsyncTask 类中运行此代码。

我的问题是,我怎样才能使我的代码更有效地执行此代码以更精确地触发;尽可能准确地接近每 150 毫秒?谢谢阅读!

编辑: 作为建议在另一个线程中运行,我尝试添加此代码:

...
                performOnBackgroundThread(new Runnable(){

                    @SuppressWarnings("unchecked")
                    @Override
                    public void run() {
                        try {
                            final DefaultHttpClient httpclient = new DefaultHttpClient();
                            final ResponseHandler responseHandler = new BasicResponseHandler();

                            httpclient.execute(put, responseHandler);
                        } catch (ClientProtocolException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                    }

                });
...

public static Thread performOnBackgroundThread(final Runnable runnable) {
    final Thread t = new Thread() {
        @Override
        public void run() {
            try {
                runnable.run();
            } finally {

            }
        }
    };
    t.start();
    return t;
}

但是我的应用程序很快因“I/Process(18762): Sending signal.PID: 18762 SIG: 9”而崩溃,而且我也遇到了一堆这样的错误。

02-10 00:14:58.639: W/SingleClientConnManager(18762): Invalid use of SingleClientConnManager: connection still allocated.
02-10 00:14:58.639: W/SingleClientConnManager(18762): Make sure to release the connection before allocating another one.
02-10 00:14:58.639: W/SingleClientConnManager(18762): Invalid use of SingleClientConnManager: connection still allocated.
02-10 00:14:58.639: W/SingleClientConnManager(18762): Make sure to release the connection before allocating another one.
02-10 00:14:58.647: W/System.err(18762): java.net.SocketException: Socket closed
02-10 00:14:58.647: W/System.err(18762):    at libcore.io.Posix.recvfromBytes(Native Method)
02-10 00:14:58.647: W/System.err(18762):    at libcore.io.Posix.recvfrom(Posix.java:131)
02-10 00:14:58.647: W/System.err(18762):    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
02-10 00:14:58.647: W/System.err(18762):    at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
02-10 00:14:58.647: W/System.err(18762):    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
02-10 00:14:58.647: W/System.err(18762):    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
02-10 00:14:58.647: W/System.err(18762):    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
02-10 00:14:58.647: W/System.err(18762):    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
02-10 00:14:58.655: W/System.err(18762):    at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:191)
02-10 00:14:58.655: W/System.err(18762):    at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:82)
02-10 00:14:58.655: W/System.err(18762):    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:174)
02-10 00:14:58.655: W/System.err(18762):    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:180)
02-10 00:14:58.655: W/System.err(18762):    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:235)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:259)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:279)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:428)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:653)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
02-10 00:14:58.663: W/System.err(18762):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
02-10 00:14:58.663: W/System.err(18762):    at com.<takenout>.<takenout>.<takenout>.run(MyFile.java:79)
02-10 00:14:58.663: W/System.err(18762):    at com.<takenout>.<takenout>.<takenout>.run(MyFile.java:116)
02-10 00:14:58.671: W/System.err(18762): java.net.SocketTimeoutException
02-10 00:14:58.671: W/System.err(18762):    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:491)
02-10 00:14:58.671: W/System.err(18762):    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
02-10 00:14:58.671: W/dalvikvm(18762): threadid=17: thread exiting with uncaught exception (group=0x40d03300)

编辑#2:

02-10 00:38:08.639: W/System.err(20100): java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
02-10 00:38:08.639: W/System.err(20100):    at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:552)
02-10 00:38:08.639: W/System.err(20100):    at libcore.io.IoBridge.recvfrom(IoBridge.java:516)
02-10 00:38:08.639: W/System.err(20100):    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
02-10 00:38:08.647: W/System.err(20100):    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
02-10 00:38:08.647: W/System.err(20100):    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:191)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:82)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:174)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:180)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:235)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:259)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:279)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:428)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:653)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627)
02-10 00:38:08.647: W/System.err(20100):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616)
02-10 00:38:08.647: W/System.err(20100):    at com.<takenout>.<takenout>.<takenout>.run(MyFile.java:79)
02-10 00:38:08.647: W/System.err(20100):    at com.<takenout>.<takenout>.<takenout>.run(MyFile.java:116)
02-10 00:38:08.647: W/System.err(20100): Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
02-10 00:38:08.647: W/System.err(20100):    at libcore.io.Posix.recvfromBytes(Native Method)
02-10 00:38:08.647: W/System.err(20100):    at libcore.io.Posix.recvfrom(Posix.java:131)
02-10 00:38:08.647: W/System.err(20100):    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
02-10 00:38:08.647: W/System.err(20100):    at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
02-10 00:38:08.647: W/System.err(20100):    ... 19 more
4

1 回答 1

2

由于网络指标的差异,您真的不能 100% 保证您的服务器每 150 毫秒就会看到一次更新。您最好的选择是尝试比您想要的更快的东西,例如每 100 毫秒发送一个新请求,并希望服务器至少每 100 毫秒接收一次更新。此外,如果您发送请求的速度如此之快,请考虑使用 UDP over TCP。根据我的经验,由于确保传递数据包的开销,TCP 请求花费的时间要长得多,但是如果你丢失一两个,如果你的平均案例性能好得多,例如 90% 的时间你看到更新,这对你来说并不是什么大问题每 100 毫秒。

您目前可能会在服务器上看到延迟,因为您遇到了较早的请求,例如,如果 req1 需要 200 毫秒,req2 需要 350 毫秒,而 req3 需要 120 毫秒,那么在服务器上您不会每 150 毫秒看到一次请求。对于前几个请求尤其如此,其中网络性能可能比 5-10 个请求后的网络性能更差(例如 1-2 秒)。

我建议创建第二个 AsyncTask 类,您可以从第一个 AsyncTask 中快速生成该类(请参阅以获得一些潜在的指导)。但是,如果您如此快速地生成新的请求对象,这可能只会让您最终遇到一些线程限制。

最大的问题是你确定你在做正确的事吗?您根本不会让网络芯片组在请求之间有 150 毫秒的间隙(可能需要超过 150 毫秒才能完成执行!),所以为什么还要为许多单独的请求而烦恼呢?为什么不使用保持打开状态的套接字之类的东西(例如,谷歌 http 长轮询)?

于 2013-02-10T05:46:35.853 回答