Over t
I want to summarize and provide the final answer to safe time for other developers.
Is android.os.StrictMode$InstanceCountViolation a problem or not
This can be a real problem. To identify if this is a problem I can recommend the following post: Detecting leaked Activities in Android. If you will see that there are objects holding a reference to this activity which don't related to Android Framework then you have a problem which should be fixed by you.
In case there are no objects holding a reference to this activity which don't related to Android Framework than it means that you encountered with the problem related to how detectActivityLeaks check is implemented. Also as was pointed the garbage collection should help in this case
Why detectActivityLeaks works incorrectly and reproduces not on all devices
If we will look at sources of the detectActivityLeaks:
// Note: adding 1 here to give some breathing room during
// orientation changes. (shouldn't be necessary, though?)
limit = newExpected + 1;
...
// Quick check.
int actual = InstanceTracker.getInstanceCount(klass);
if (actual <= limit) {
return;
}
// Do a GC and explicit count to double-check.
// This is the work that we are trying to avoid by tracking the object instances
// explicity. Running an explicit GC can be expensive (80ms) and so can walking
// the heap to count instance (30ms). This extra work can make the system feel
// noticeably less responsive during orientation changes when activities are
// being restarted. Granted, it is only a problem when StrictMode is enabled
// but it is annoying.
Runtime.getRuntime().gc();
long instances = VMDebug.countInstancesOfClass(klass, false);
if (instances > limit) {
Throwable tr = new InstanceCountViolation(klass, instances, limit);
onVmPolicyViolation(tr.getMessage(), tr);
}
The problem here is that to count instances correctly, all previous ones should be garbage collected (at least logic is relay on this). And this is the main problem of this implementation. The reason why is that one round trip of the GC can't be enough in Java if you want to be sure that all objects which are ready to be released are collected by GC. In most cases it is enough to call System.gc() twice or use something similar to methods implemented in this jlibs library.
That's why this issue reproduces on some devices (OS versions) and doesn't reproduce on another ones. This all depends on how GC is implemented and sometimes only one call is enough to be sure that object will be collected by GC.
How to avoid this issue in case there is no leaked Activities I simply run System.gc() before starting activity in debug configuration like in the following example. This will help to avoid this problem and gives you ability to continue using detectActivityLeaks check.
if (BuildConfig.DEBUG)
{
System.gc();
}
Intent intent = new Intent(context, SomeActivity.class);
this.startActivity(intent);
This also ensures that in release build Garbage Collection is not forced as this is not recommended.