关键字: 应用统计 Android源码 应用使用时长 应用使用次数
上篇文章讲到LocalService以及BinderService都是调用了UserUsageStatsService的相关函数接口,实现相关功能。以下,主要分为记录和查询两个方面对UserUsageStatsService进行解析。
数据的记录
上篇文章曾讲到,不论是Event还是ConfigurationChange,都是调用UserUsageStatsService.reportEvent(event)这一函数,用来记录event和config数据。
void reportEvent(UsageEvents.Event event) {
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
+ "[" + event.mTimeStamp + "]: "
+ eventToString(event.mEventType));
}
if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
// Need to rollover
//切换文件(因为一个文件仅记录当天的数据,如果数据的时间超过了当天的标记时间,则需要新建另一文件,记录第二天的数据)
rolloverStats(event.mTimeStamp);
}
final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
final Configuration newFullConfig = event.mConfiguration;
if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE &&
currentDailyStats.activeConfiguration != null) {
// Make the event configuration a delta.
event.mConfiguration = Configuration.generateDelta(
currentDailyStats.activeConfiguration, newFullConfig);
}
// Add the event to the daily list.
//将event数据计入统计数据中。
if (currentDailyStats.events == null) {
currentDailyStats.events = new TimeSparseArray<>();
}
currentDailyStats.events.put(event.mTimeStamp, event);
//依次更新日,周,月,年的统计数据
for (IntervalStats stats : mCurrentStats) {
if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE) {
stats.updateConfigurationStats(newFullConfig, event.mTimeStamp);
} else {
stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
}
}
//关键:下一函数最终会调用上篇文章讲到的flushToDiskLocked(),用于将数据写入文件,而flushToDiskLocked()调用的是UserUsageStatsService.persistActiveStats()
notifyStatsChanged();
}
综