I need to get an unique id of an android activity instance. I\'d like to take the string which the activitymanager writes in the log (for example: ActivityManager: Activity
As correctly pointed out in the other answer, activities can be recreated by the OS, so using Activity.hashCode()
is not a reliable solution. Moreover, the whole app process can be recreated (after permission change, for example), which means any runtime/non-persisted ID cannot be trusted. A correct solution is manually generate a unique ID during onCreate(Bundle)
(or read it from savedInstanceState
, if exists) and save it during onSaveInstanceState(Bundle)
.
Another problem is generating truly unique ID. The simplest and most reliable solution is too keep a static counter, but since app process may die, it requires a little more care.
To bring boilerplate code to a minimum, I've put together a specialized class:
public class ActivityUUID {
private static final String INSTANCE_DATA_ID = "BwsKCwYBDg8GAQ4LBAgAAA"; // NOTE Any globally unique ID
private static final String UUID_NODE_ID = "a";
private static final long INVALID_UUID = 0;
private static long _lastActivityUUID = INVALID_UUID; // NOTE All activity callbacks are guaranteed to be made from UI thread, so no synchronization is required
private static SharedPreferences _persistentData;
private final long _uuid;
public ActivityUUID(Context context, Bundle savedInstanceState) {
_uuid = readUUID(context, savedInstanceState);
}
public long get() {
return _uuid;
}
public void onSaveInstanceState(Bundle outState) {
outState.putLong(INSTANCE_DATA_ID, _uuid);
}
private static long readUUID(Context context, Bundle savedInstanceState) {
long result = (savedInstanceState != null) ? savedInstanceState.getLong(INSTANCE_DATA_ID, INVALID_UUID) : INVALID_UUID;
return (result != INVALID_UUID) ? result : generateUUID(context);
}
private static long generateUUID(Context context) {
if (_persistentData == null) {
_persistentData = context.getSharedPreferences(INSTANCE_DATA_ID, Context.MODE_PRIVATE);
_lastActivityUUID = _persistentData.getLong(UUID_NODE_ID, INVALID_UUID);
}
long result = ++_lastActivityUUID;
if (result != INVALID_UUID) {
_persistentData.edit().putLong(UUID_NODE_ID, result).apply();
} else {
throw new RuntimeException("You have somehow managed to create a total of 9223372036854775807 activities during lifetime of your app! =)");
}
return result;
}
}
Usage is pretty simple:
private ActivityUUID _activityUUID;
@Override
public final void onCreate(Bundle savedInstanceState) {
_activityUUID = new ActivityUUID(this, savedInstanceState);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
_activityUUID.onSaveInstanceState(outState);
}
// ...somewhere else in the code
long activityUUID = _activityUUID.get();