5

アプリのデータ使用量を追跡したいのですが、そのためには と のフルサイズを取得できる必要がHttpUriRequestありHttpResponseます。リクエストとレスポンスの両方で転送されるデータ (ヘッダー、パラメータ、実際に送信される URL など) が増えるため、単に のサイズを取得するだけでHttpEntityは十分ではありません。では、双方向に送信されている全量のデータを見つける方法はありますか?

ありがとう。

4

1 に答える 1

6

「後で」メトリックが必要な場合は、適切な実装の独自のサブクラスを提供し、リクエストがマネージャーに返された後にClientConnectionManager関連するものをフェッチするだけです。HttpConnectionMetrics

単純な (そして少しおしゃべりな) 例として、 subclassSingleClientConnManagerは次のようになります。

class MeasuringClientConnManager extends SingleClientConnManager {
    private long mReceivedBytes = -1;
    private long mSentBytes = -1;
    public MeasuringClientConnManager(HttpParams params, SchemeRegistry schreg) {
        super(params, schreg);
    }
    @Override
    public void releaseConnection(ManagedClientConnection conn,
            long validDuration, TimeUnit timeUnit) {
        HttpConnectionMetrics metrics = conn.getMetrics();
        mReceivedBytes = metrics.getReceivedBytesCount();
        mSentBytes = metrics.getSentBytesCount();
        metrics.reset();
        super.releaseConnection(conn, validDuration, timeUnit);
    }

    public long getReceivedBytes() {
        return mReceivedBytes;
    }
    public long getSentBytes() {
        return mSentBytes;
    }
}

次のように HTTP クライアントに詰め込むだけです。

BasicHttpParams params = new BasicHttpParams();
SchemeRegistry schreg = new SchemeRegistry();
schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Add SSL here if you need it
MeasuringClientConnManager conman = new MeasuringClientConnManager(params, schreg);
DefaultHttpClient client = new DefaultHttpClient(conman, params);
client.execute(new HttpGet("http://www.google.com"));
System.out.println(conman.getSentBytes());
System.out.println(conman.getReceivedBytes());

編集:ログセッションの入力および出力バッファを破損したワイヤログと一緒に使用し、リスナーインターフェイスを追加する代替例。

class MeasuringClientConnManager extends SingleClientConnManager {

    interface WireListener {
        void onUpdate(long sent, long recv);
    }
    private WireListener mListener;
    private long mReceivedBytes = -1;
    private long mSentBytes = -1;
    private Wire mWire = new Wire(null) {
        public boolean enabled() { return true; };
        // Time to override a bunch of methods (otherwise Wire will crash)
        public void input(byte[] b) throws IOException {mReceivedBytes += b.length; rxtx();};
        public void input(byte[] b, int off, int len) throws IOException {mReceivedBytes += len; rxtx();}
        public void input(InputStream instream) throws IOException {mReceivedBytes += count(instream); rxtx();}
        public void input(String s) throws IOException {mReceivedBytes += s.length(); rxtx();};
        public void input(int b) throws IOException {mReceivedBytes++; rxtx();}
        public void output(byte[] b) throws IOException {mSentBytes += b.length; rxtx();}
        public void output(byte[] b, int off, int len) throws IOException {mSentBytes += len; rxtx();}
        public void output(int b) throws IOException {mSentBytes++; rxtx();}
        public void output(String s) throws IOException {mSentBytes += s.length(); rxtx();}
        public void output(InputStream outstream) throws IOException {mSentBytes += count(outstream); rxtx();};

        private int count(InputStream is) throws IOException {
            int result = 0;
            byte[] b = new byte[1024 * 8];
            int count;
            while ((count = is.read(b)) > -1) {
                result += count;
            }
            return result;
        }
    };

    public MeasuringClientConnManager(HttpParams params, SchemeRegistry schreg) {
        super(params, schreg);
    }

    public void setWireListener(WireListener wl) {
        mListener = wl;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected ClientConnectionOperator createConnectionOperator(
            SchemeRegistry schreg) {
        final ClientConnectionOperator actual = super.createConnectionOperator(schreg);
        ClientConnectionOperator wired = new ClientConnectionOperator() {
            @Override
            public void updateSecureConnection(OperatedClientConnection conn,
                    HttpHost target, HttpContext context, HttpParams params)
                    throws IOException {
                actual.updateSecureConnection(conn, target, context, params);
            }
            @Override
            public void openConnection(OperatedClientConnection conn, HttpHost target,
                    InetAddress local, HttpContext context, HttpParams params)
                    throws IOException {
                actual.openConnection(conn, target, local, context, params);
            }

            @Override
            public OperatedClientConnection createConnection() {
                DefaultClientConnection conn = new DefaultClientConnection() {
                    @Override
                    protected SessionInputBuffer createSessionInputBuffer(
                            Socket socket, int buffersize, HttpParams params)
                            throws IOException {
                        return new LoggingSessionInputBuffer(super.createSessionInputBuffer(socket, buffersize, params), mWire);
                    }
                    @Override
                    protected SessionOutputBuffer createSessionOutputBuffer(
                            Socket socket, int buffersize, HttpParams params)
                            throws IOException {
                        return new LoggingSessionOutputBuffer(super.createSessionOutputBuffer(socket, buffersize, params), mWire);
                    }
                };
                return conn;
            }
        };
        return wired;
    }

    void rxtx() {
        WireListener l = mListener;
        if (l != null) {
            l.onUpdate(mSentBytes, mReceivedBytes);
        }
    }
}

使用法は非常に似ていますが、現在は送信時にワイヤ更新が行われています:

BasicHttpParams params = new BasicHttpParams();
SchemeRegistry schreg = new SchemeRegistry();
schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Add SSL here if you need it
MeasuringClientConnManager conman = new MeasuringClientConnManager(params, schreg);
conman.setWireListener(new MeasuringClientConnManager.WireListener() {
    @Override
    public void onUpdate(long sent, long recv) {
        System.out.println("WIRE sent: " + sent + ", recv: " + recv);
    }
});
DefaultHttpClient client = new DefaultHttpClient(conman, params);
client.execute(new HttpGet("http://www.thirdbase.se"));
于 2012-05-28T20:03:03.423 に答える