有没有办法找到HTTP请求和响应在Android上的全尺寸(用于数据使用情况跟踪)? [英] Is there a way to find the full size of HTTP Request and response in Android (for data usage tracking)?

查看:221
本文介绍了有没有办法找到HTTP请求和响应在Android上的全尺寸(用于数据使用情况跟踪)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想跟踪我的应用程序的数据使用量,但要做到这一点,我需要能够得到一个 HttpUriRequest 和<$ C的全尺寸$ C>的Htt presponse 。简单地获取的 HttpEntity 是远远不够的,因为无论是请求和响应有更多的数据被传输(头,参数,可以传送实际的URL等)的大小。那么,有没有办法找到数据的正在被传送两种方式全款?

i would like to track the data usage of my app, but to do that, I need to be able to get the full size of an HttpUriRequest and HttpResponse. Simply getting the size of the HttpEntity isn't enough because both the request and response have more data being transferred (headers, params, the actual URL being transmitted, etc). So, is there a way to find the full amount of data that's being transmitted both ways?

感谢。

推荐答案

如果您只想指标事后你可以提供你自己的合适 ClientConnectionManager 实现子类并获取相关的 HttpConnectionMetrics

If you just want metrics "afterwards" you can just supply your own subclass of a suitable ClientConnectionManager implementation and fetch the relevant HttpConnectionMetrics after the request is returned to the manager.

作为一个简单的(略低SH * TTY)为例,子类 SingleClientConnManager ,像这样:

As a simple (and slighty sh*tty) example, subclass SingleClientConnManager, like so:

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客户端,像这样:

and just cram it into your HTTP client like so:

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

修改:使用记录会话的输入和放大器变形例;输出缓冲器旁边一个错位的线数+添加一个监听器接口。

Edit: Alternative example that uses logging session input & output buffers alongside a mangled wire log + adding a listener interface.

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

用法十分相似,但现在用铁丝更新,东东被送到:

Usage is very similar, but now with wire updates as stuff is sent:

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

这篇关于有没有办法找到HTTP请求和响应在Android上的全尺寸(用于数据使用情况跟踪)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆