有人能解释TrafficStats如何工作它的魔力在Android OS? [英] Can someone explain how TrafficStats works its magic in the Android OS?

查看:195
本文介绍了有人能解释TrafficStats如何工作它的魔力在Android OS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个可爱的小Android应用程序来检查数据的使用,遗憾的是它在很大程度上依赖于被介绍与升级Froyo(And​​roid 2.2的)android.net.TrafficStats。

我试图回港这个类我非Froyo的用户,就是我能够确定从<一个href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/jni/android_net_TrafficStats.cpp;h=ff46bdd2ba39380a0a673cbf8aadfc5a3529156c;hb=refs/heads/master1.">Android来源是:

  1. TrafficStats.java仅仅是一个原生指针交流文件
  2. 在C文件打开了两个文件(见下文),并读取其内容
  3. 如果任一包含它吐出回为使用的字节的数值计数

下面是我的挑战......当我打电话通过API TrafficStats我的设备上,我得到一个读(例如,1113853字节)。当我打开这两个文件,​​并检查它们的内容,一个文件不存在,而另一个文件是0字节。

所以显然我错明白TrafficStats在做什么。任何人都可以阐明它是如何工作它的魔力一些轻?

感谢您的帮助。

(这里是我的尝试端口C文件到Java)

 包com.suttco.net;

进口的java.io.File;
进口java.io.FileNotFoundException;
进口java.io.IOException异常;

进口com.suttco.IOUtils;
进口com.suttco.StringUtils;

进口android.util.Log;

公共类TrafficStatsFile {

 私有静态最后弦乐mobileRxFile_1 =/ SYS /班/ NET / rmnet0 /统计/ rx_bytes;
 私有静态最后弦乐mobileRxFile_2 =/ SYS /班/ NET / ppp0的/统计/ rx_bytes;
 私有静态最后弦乐mobileTxFile_1 =/ SYS /班/ NET / rmnet0 /统计/ tx_bytes;
 私有静态最后弦乐mobileTxFile_2 =/ SYS /班/ NET / ppp0的/统计/ tx_bytes;

 私有静态最后弦乐LOGGING_TAG = TrafficStatsFile.class.getSimpleName();

 众长getMobileRxBytes(){
  返回tryBoth(mobileRxFile_1,mobileRxFile_2);
 }

 众长getMobileTxBytes(){
  返回tryBoth(mobileTxFile_1,mobileTxFile_2);
 }

 //返回的人数从它存在并包含数据的第一个文件
 私有静态长tryBoth(一个字符串,字符串B){
  长NUM = readNumber(一);
  返回民&GT; = 0? NUM:readNumber(B);
 }

 //返回指定文件中读取一个ASCII十进制数,1的错误。
 私有静态长readNumber(字符串文件名){
  文件F =新的文件(文件名);
  如果(f.exists()){
   如果(f.canRead()){
    尝试 {
     Log.d(LOGGING_TAG,f.length()=+ f.length());
     字符串内容= IOUtils.readFileAsString(F);
     如果(StringUtils.IsNotNullOrEmpty(内容)){
      尝试 {
       返回的Long.parseLong(内容);
      }
      赶上(NumberFormatException的nfex){
       Log.w(LOGGING_TAG,文件内容是不是数字:+文件名);
      }
     }
     其他 {
      Log.w(LOGGING_TAG,文件内容为空:+文件名);
     }
    }
    赶上(FileNotFoundException异常fnfex){
     Log.w(LOGGING_TAG,找不到文件:+文件名,fnfex);
    }
    赶上(IOException异常ioex){
     Log.w(LOGGING_TAGIOException异常:+文件名,ioex);
    }
   }
   其他 {
    Log.w(LOGGING_TAG,无法读取文件:+文件名);
   }
  }
  其他 {
   Log.w(LOGGING_TAG,文件不存在+文件名);
  }
  返回-1;
 }
}
 

解决方案

下面是的code以上工作,修改后的版本。这一个是使用的RandomAccessFile 和不依赖于定制进口,但只使用内置的字符串例外功能

 进口java.io.FileNotFoundException;
进口java.io.IOException异常;
进口java.io.RandomAccessFile中;

进口android.util.Log;

公共类TrafficStatsFile {

私有静态最后弦乐mobileRxFile_1 =/ SYS /班/ NET / rmnet0 /统计/ rx_bytes;
私有静态最后弦乐mobileRxFile_2 =/ SYS /班/ NET / ppp0的/统计/ rx_bytes;
私有静态最后弦乐mobileTxFile_1 =/ SYS /班/ NET / rmnet0 /统计/ tx_bytes;
私有静态最后弦乐mobileTxFile_2 =/ SYS /班/ NET / ppp0的/统计/ tx_bytes;

私有静态最后弦乐LOGGING_TAG = TrafficStatsFile.class.getSimpleName();

众长getMobileRxBytes(){
    返回tryBoth(mobileRxFile_1,mobileRxFile_2);
}

众长getMobileTxBytes(){
    返回tryBoth(mobileTxFile_1,mobileTxFile_2);
}

//返回的人数从它存在并包含数据的第一个文件
私有静态长tryBoth(一个字符串,字符串B){
    长NUM = readNumber(一);
    返回民&GT; = 0? NUM:readNumber(B);
}

//返回指定文件中读取一个ASCII十进制数,1的错误。
私有静态长readNumber(字符串文件名){
    尝试 {
        RandomAccessFile的F =新RandomAccessFile的(文件名,R);
        尝试 {
            Log.d(LOGGING_TAG,f.length()=+ f.length());
            字符串内容= f.readLine();
            如果(contents.isEmpty()及!&安培;!内容= NULL){
                尝试 {
                    返回的Long.parseLong(内容);
                }
                赶上(NumberFormatException的nfex){
                    Log.w(LOGGING_TAG,文件内容是不是数字:+文件名);
                }
            }
            其他 {
                Log.w(LOGGING_TAG,文件内容为空:+文件名);
            }
        }
        赶上(FileNotFoundException异常fnfex){
            Log.w(LOGGING_TAG,找不到文件:+文件名,fnfex);
        }
        赶上(IOException异常ioex){
            Log.w(LOGGING_TAGIOException异常:+文件名,ioex);
        }
    }赶上(FileNotFoundException异常FFE){
        Log.w(LOGGING_TAG,找不到文件:+文件名,FFE);
    }
    返回-1;
}

}
 

I've written a nice little Android app to check data usage, unfortunately it relies heavily on android.net.TrafficStats which was introduced with Froyo (Android 2.2).

I'm attempting to back-port this class for my non-Froyo users, and what I'm able to determine from the Android source is:

  1. TrafficStats.java is just a native pointer to a c file
  2. The c file opens two files (see below) and reads their contents
  3. If either contains a numeric value it spits it back as the "bytes used" count

Here's my challenge... when I call TrafficStats via the API on my device, I get a reading (ex. 1113853 bytes). When I open the two files and check their contents, one file doesn't exist and the other file is 0 bytes.

So clearly I mis-understood what TrafficStats is doing. Can anyone shed some light on how it's working it's magic?

Thanks for the help.

(here is my attempt to port the c file to java)

package com.suttco.net;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import com.suttco.IOUtils;
import com.suttco.StringUtils;

import android.util.Log;

public class TrafficStatsFile {

 private static final String mobileRxFile_1 = "/sys/class/net/rmnet0/statistics/rx_bytes";
 private static final String mobileRxFile_2 = "/sys/class/net/ppp0/statistics/rx_bytes";
 private static final String mobileTxFile_1 = "/sys/class/net/rmnet0/statistics/tx_bytes";
 private static final String mobileTxFile_2 = "/sys/class/net/ppp0/statistics/tx_bytes";

 private static final String LOGGING_TAG = TrafficStatsFile.class.getSimpleName();

 public long getMobileRxBytes() {
  return tryBoth(mobileRxFile_1, mobileRxFile_2);
 }

 public long getMobileTxBytes() {
  return tryBoth(mobileTxFile_1, mobileTxFile_2);
 }

 // Return the number from the first file which exists and contains data
 private static long tryBoth(String a, String b) {
  long num = readNumber(a);
  return num >= 0 ? num : readNumber(b);
 }

 // Returns an ASCII decimal number read from the specified file, -1 on error.
 private static long readNumber(String filename) {
  File f = new File(filename);
  if(f.exists()) {
   if(f.canRead()) {
    try {
     Log.d(LOGGING_TAG, "f.length() = " + f.length());
     String contents = IOUtils.readFileAsString(f);
     if(StringUtils.IsNotNullOrEmpty(contents)) {
      try {
       return Long.parseLong(contents);
      }
      catch(NumberFormatException nfex) {
       Log.w(LOGGING_TAG, "File contents are not numeric: " + filename); 
      }
     }
     else {
      Log.w(LOGGING_TAG, "File contents are empty: " + filename); 
     }
    }
    catch (FileNotFoundException fnfex) {
     Log.w(LOGGING_TAG, "File not found: " + filename, fnfex);
    }
    catch(IOException ioex) {
     Log.w(LOGGING_TAG, "IOException: " + filename, ioex);
    }
   }
   else {
    Log.w(LOGGING_TAG, "Unable to read file: " + filename);
   }
  }
  else {
   Log.w(LOGGING_TAG, "File does not exist: " + filename);
  }
  return -1;
 }
}

解决方案

Here's a working, modified version of the code above. This one is using RandomAccessFile and doesn't rely on custom imports but uses only built-in String functions with their Exceptions.

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

import android.util.Log;

public class TrafficStatsFile {

private static final String mobileRxFile_1 = "/sys/class/net/rmnet0/statistics/rx_bytes";
private static final String mobileRxFile_2 = "/sys/class/net/ppp0/statistics/rx_bytes";
private static final String mobileTxFile_1 = "/sys/class/net/rmnet0/statistics/tx_bytes";
private static final String mobileTxFile_2 = "/sys/class/net/ppp0/statistics/tx_bytes";

private static final String LOGGING_TAG = TrafficStatsFile.class.getSimpleName();

public long getMobileRxBytes() {
    return tryBoth(mobileRxFile_1, mobileRxFile_2);
}

public long getMobileTxBytes() {
    return tryBoth(mobileTxFile_1, mobileTxFile_2);
}

// Return the number from the first file which exists and contains data
private static long tryBoth(String a, String b) {
    long num = readNumber(a);
    return num >= 0 ? num : readNumber(b);
}

// Returns an ASCII decimal number read from the specified file, -1 on error.
private static long readNumber(String filename) {
    try {
        RandomAccessFile f = new RandomAccessFile(filename, "r");
        try {
            Log.d(LOGGING_TAG, "f.length() = " + f.length());
            String contents = f.readLine();
            if(!contents.isEmpty() && contents!=null) {
                try {
                    return Long.parseLong(contents);
                }
                catch(NumberFormatException nfex) {
                    Log.w(LOGGING_TAG, "File contents are not numeric: " + filename); 
                }
            }
            else {
                Log.w(LOGGING_TAG, "File contents are empty: " + filename); 
            }
        }
        catch (FileNotFoundException fnfex) {
            Log.w(LOGGING_TAG, "File not found: " + filename, fnfex);
        }
        catch(IOException ioex) {
            Log.w(LOGGING_TAG, "IOException: " + filename, ioex);
        }   
    }catch(FileNotFoundException ffe){
        Log.w(LOGGING_TAG, "File not found: " + filename, ffe);
    }
    return -1;
}

}

这篇关于有人能解释TrafficStats如何工作它的魔力在Android OS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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