在我的应用中,多个App Widgets可以放置在主屏幕上,每个小部件定期获取远程数据。分别跟踪多个应用小部件的数据使用情况
我的目标是:与各多个小部件的相关分开
- 跟踪数据使用
- 没有额外的权限
- 允许小部件同时执行网络操作而不重复计算数据使用率
- 包括
WebView
活动数据使用来自小部件中发起 - 报告结果应用程序内(不只是当拴在网络通信工具)
这是很容易的登录数据使用你自己的UID前,一个小部件后通过使用getUidRxBytes()
和getUidTxBytes()
(通过您自己的应用程序的UID)更新为TrafficStats
,然后采取差异。虽然这种粗糙和准备的方法在小部件串联运行时给出了明智的价值,但是当它们同时运行时,不可避免地会出现一定程度的双重(三重等)计数。
我宁愿不强制小部件进行系列更新,因为我宁愿让设备的作业调度引擎找出最好的方法。所以我需要一种方法来将每个小部件的数据使用分开。
似乎标签的使用可能是...的方式标记网络运营的appWidgetId
,然后过滤基于这个appWidgetId
统计。我不相信这种方法将实际上使一个小部件的数据使用与另一个小部件区分开来(也许这些存储桶会变得混乱),但事实是我无法让标签工作,所以我不能但告诉。
在网络操作开始之前,您可以使用setThreadStatsTag(tag)
设置标记,但在TrafficStats
类中看不到任何用于检索按标记过滤的结果的方法。 有谁知道有什么不同?
所以我再看看NetworkStatsManager,特别是NetworkStatsManager.queryDetailsForUidTag(... , tag)
。这似乎允许你基于特定的tag
进行过滤,并且没有任何额外的权限(对于你自己的应用程序的UID),这是很好的。但是我不能用这种方法返回任何带有数据的桶,尽管在使用HttpURLConnection
的网络操作之前设置了TrafficStats.setThreadStatsTag(appWidgetId)
,并且之后通过调用NetworkStatsManager.queryDetailsForUidTag(... , appWidgetId)
用相同的标签查询。
在另一方面,NetworkStatsManager.queryDetailsForUid()
(无tag
参数)确实有效的数据返回水桶,所以它似乎只是不工作,而不是什么我做错了与NetworkStatsManager
每根本的标签SE。
我设定的标签:
@Override
protected void onPreExecute() {
TrafficStats.setThreadStatsTag(appWidgetId);
}
@Override
protected Bitmap doInBackground(String... baseUrls) {
// fetch data with HttpURLConnection
}
@Override
protected void onPostExecute(Bitmap bmp) {
TrafficStats.clearThreadStatsTag();
}
和(对于WiFi数据),我查询与统计:
void networkStatsStuff() {
NetworkStats networkStats;
NetworkStats networkStatsTagged;
int networkType = ConnectivityManager.TYPE_WIFI;
try {
networkStats = networkStatsManager.queryDetailsForUid(networkType, "", startTime, endTime, myUid);
} catch (RemoteException e) {
return;
}
networkStatsTagged = networkStatsManager.queryDetailsForUidTag(networkType, "", startTime, endTime, myUid, appWidgetId);
long totalData = getTotalData(networkStats);
long totalDataTagged = getTotalData(networkStatsTagged);
Log.d(TAG, "totalData: " + totalData); // this seems to work
Log.d(TAG, "totalDataTagged: " + totalDataTagged); // this is always zero
}
long getTotalData(NetworkStats networkStats) {
long totalData = 0;
do {
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
totalData = totalData + bucket.getRxBytes() + bucket.getTxBytes();
} while (networkStats.hasNextBucket());
return totalData;
}
我在做什么错? (编辑:部分答案在下面)或者也许有一种完全不同的方式来实现我的目标?