返回

Android项目复盘之应用使用时长和使用次数统计存在的问题与解决方案

Android

前言

在我们的Android项目中,我们需要统计应用的使用时长和使用次数。为此,我们使用了以下方法:

  • 当每次打开应用的时候,通过上述方法去取使用数据。
  • 或者每次从应用其他页面回到首页的时候去取,将取到的数据持久化保存到本地数据库。

这种使用方式看起来很合理,但是测试人员总是反馈应该记录的使用时长和使用次数和实际不符,那么问题究竟出在哪里呢?

问题分析

为了找到问题的原因,我们首先对业务逻辑和源码进行了分析。我们发现,在应用的MainActivity中,有以下代码:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 获取使用时长和使用次数
    long usageTime = UsageStatsManager.getInstance(this).getAppUsageStats(UsageStatsManager.INTERVAL_DAILY);
    int usageCount = UsageStatsManager.getInstance(this).getAppUsageStats(UsageStatsManager.INTERVAL_DAILY);

    // 将数据持久化保存到本地数据库
    UsageData usageData = new UsageData();
    usageData.setUsageTime(usageTime);
    usageData.setUsageCount(usageCount);
    usageDataDao.insert(usageData);
}

这段代码在应用每次打开的时候都会获取使用时长和使用次数,然后将数据持久化保存到本地数据库。这似乎没有问题,但是实际上,这段代码存在一个问题:它只会在应用每次打开的时候获取数据,而不会在应用从其他页面回到首页的时候获取数据。

解决办法

为了解决这个问题,我们修改了代码,使得它会在每次从应用其他页面回到首页的时候也获取数据。修改后的代码如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 获取使用时长和使用次数
    long usageTime = UsageStatsManager.getInstance(this).getAppUsageStats(UsageStatsManager.INTERVAL_DAILY);
    int usageCount = UsageStatsManager.getInstance(this).getAppUsageStats(UsageStatsManager.INTERVAL_DAILY);

    // 将数据持久化保存到本地数据库
    UsageData usageData = new UsageData();
    usageData.setUsageTime(usageTime);
    usageData.setUsageCount(usageCount);
    usageDataDao.insert(usageData);

    // 注册一个监听器,当应用从其他页面回到首页的时候,获取数据
    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
        @Override
        public void onActivityResumed(Activity activity) {
            if (activity instanceof MainActivity) {
                // 获取使用时长和使用次数
                long usageTime = UsageStatsManager.getInstance(activity).getAppUsageStats(UsageStatsManager.INTERVAL_DAILY);
                int usageCount = UsageStatsManager.getInstance(activity).getAppUsageStats(UsageStatsManager.INTERVAL_DAILY);

                // 将数据持久化保存到本地数据库
                UsageData usageData = new UsageData();
                usageData.setUsageTime(usageTime);
                usageData.setUsageCount(usageCount);
                usageDataDao.insert(usageData);
            }
        }

        @Override
        public void onActivityPaused(Activity activity) {

        }

        @Override
        public void onActivityStarted(Activity activity) {

        }

        @Override
        public void onActivityStopped(Activity activity) {

        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

        }

        @Override
        public void onActivityDestroyed(Activity activity) {

        }
    });
}

修改后的代码不仅会在应用每次打开的时候获取数据,还会在应用从其他页面回到首页的时候获取数据。这样,我们就可以准确地统计应用的使用时长和使用次数了。

总结

通过这次项目复盘,我们吸取了以下教训:

  • 在设计应用的业务逻辑和编写代码的时候,一定要考虑到所有的情况。
  • 在测试应用的时候,一定要对应用的各个功能进行全面的测试。
  • 在发现问题的时候,一定要及时分析问题的原因并解决问题。