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

ネットワーク メトリックの変動により、サーバーが 150 ミリ秒ごとに更新されることを 100% 保証することはできません。最善の策は、100 ミリ秒ごとに新しい要求を送信し、少なくとも 100 ミリ秒ごとにサーバーが更新を受信することを期待するなど、希望よりも速いものを試すことです。さらに、リクエストをこれほど迅速に送信する場合は、UDP over TCP の使用を検討してください。私の経験では、TCP リクエストは、パケットが確実に配信されるようにするためのオーバーヘッドにより、はるかに時間がかかりますが、1 つまたは 2 つの損失があったとしても、平均的なケースのパフォーマンスがはるかに優れている場合、たとえば 90% の時間で更新が表示される場合、大したことではありません。 100msごと。

たとえば、req1 に 200 ミリ秒、req2 に 350 ミリ秒、req3 に 120 ミリ秒かかる場合、サーバーでは 150 ミリ秒ごとにリクエストが表示されません。これは特に最初の数回のリクエストに当てはまり、5 ~ 10 回のリクエストの後ではネットワーク パフォーマンスが大幅に低下する可能性があります (例: 1 ~ 2 秒)。

最初の AsyncTask から迅速に生成する 2 番目の AsyncTask クラスを作成することをお勧めします (潜在的なガイダンスについては、こちらを参照してください)。ただし、これは、新しい要求オブジェクトを非常に迅速に生成している場合に、最終的にいくつかのスレッド制限に遭遇する場合に限られます。

大きな問題は、あなたが正しいことをしていると確信していますか? リクエスト間の 150 ミリ秒のギャップ (実行が完了するまでに 150 ミリ秒以上かかる可能性があります!) で、ネットワーク チップセットをまったくスリープ状態にしないでください。開いたままのソケットのようなものを使用しないのはなぜですか (たとえば、Google http long polling など)。

于 2013-02-10T05:46:35.853 に答える