当前位置: 首页 > 面试题库 >

有没有办法找到Android中HTTP请求和响应的完整大小(用于数据使用情况跟踪)?

濮阳靖
2023-03-14
问题内容

我想跟踪我的应用程序的数据使用,但要做到这一点,我需要能够得到的全尺寸HttpUriRequestHttpResponse。仅获取的大小HttpEntity是不够的,因为请求和响应都传输了更多的数据(标头,参数,正在传输的实际URL等)。那么,有没有办法找到双向传输的全部数据呢?

谢谢。


问题答案:

如果只希望度量“之后”,则可以提供适合自己的ClientConnectionManager实现的子类,并HttpConnectionMetrics在将请求返回给管理器之后获取相关的子类。

作为一个简单的示例(以及一点点sh * tty),subclass SingleClientConnManager像这样:

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


 类似资料:
  • 我想跟踪我的应用程序的数据使用情况,但要做到这一点,我需要能够获得和的完整大小。仅仅获取的大小是不够的,因为请求和响应都传输了更多的数据(头、参数、传输的实际URL等)。那么,有没有办法找到双向传输的全部数据量? 谢谢

  • 我正在使用Volley向API发出GET请求: 预期的JSON对象响应很大(可能高达500 KB)。我无法在日志中看到完整的响应。仅显示前50行左右。我还得到了info: BasicNetwork.log慢速请求:请求的HTTP响应= 这意味着请求需要超过3000毫秒。 尝试过的事情: 我已经在手机的开发者选项中将记录器缓冲区大小增加到1M。 原因可能是什么?当它很大的时候,响应是大块发送的吗?如

  • 在VS代码中,是否有一种方法可以使用正则表达式来查找所有使用声明变量的语句,该变量使用赋值,然后仅用替换? 我试过搜索,但找不到答案。 这是对regex的尝试(这部分工作): 这是搜索和替换部分,只是匹配的一部分,我不确定如何做,或者是否可能。 我已经组织了一次突击行动。 在这个截图中,我试图替换 通过

  • 问题内容: 这个想法是在某些情况下从另一个来源获取数据,所以我有这个存根: 失败了 [$ injector:cdep]找到循环依赖项:拦截器<-$ http 还尝试注入$ injector并使用它获取$ http,结果相同。有任何想法吗? .config就是声明: 问题答案: 注入到: 用它来获取回调函数中返回的对象。 这是一个例子

  • 我们正在运行weblogic,似乎有内存泄漏-我们最终用完了堆空间。 我们在服务器上有5个应用程序(5个war部署)。 您能想到一种方法来收集每个应用程序的内存使用情况吗? (然后我们可以通过查看相应应用程序中的代码来集中搜索。) 我已经运行jmap来获取堆转储并在jvisualvm中加载结果,但不清楚大部分对象来自何处——例如字符串。 我在想,weblogic可能会在每个应用程序中使用单独的类加

  • 我用创建了一个Android应用程序。它的工作只是完美的,但我有一个小问题。 我在中实现的web应用程序有一个Google drive按钮,当我在PC上的web浏览器上单击时,该按钮会在一个新的选项卡中打开Google authentication页面,但当我在移动应用程序中单击它时,它就不起作用了。 我只想让它重定向到用户喜欢的移动浏览器(chrome,opera等)。有办法做到吗?