Must be invoked from the UI thread