Skip to content

Commit

Permalink
Add ActivityController.close that transitions Activity to destroyed s…
Browse files Browse the repository at this point in the history
…tate

Update ActivityController to implement AutoCloseable, and add a 'close'
method that is lifecycle-aware and transitions the underlying Activity
to the destroyed state, freeing all resources and making the Activity
eligible for gc.

This is a convenient way to ensure that ActivityControllers can be freed
without having to manage the underlying Activity lifecycles.

It also enables ActivityController to be managed using
try-with-resources.

PiperOrigin-RevId: 410291892
  • Loading branch information
hoisie committed Nov 17, 2021
1 parent 662a2fe commit feaded1
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 1 deletion.
Expand Up @@ -379,6 +379,77 @@ public void windowFocusChanged() {
assertThat(controller.get().hasWindowFocus()).isTrue();
}

@Test
public void close_transitionsActivityStateToDestroyed() {
Robolectric.buildActivity(MyActivity.class).close();
assertThat(transcript).isEmpty();
transcript.clear();

Robolectric.buildActivity(MyActivity.class).create().close();
assertThat(transcript)
.containsExactly("onCreate", "finishedOnCreate", "onDestroy", "finishedOnDestroy");
transcript.clear();

Robolectric.buildActivity(MyActivity.class).create().start().close();
assertThat(transcript)
.containsExactly(
"onCreate",
"finishedOnCreate",
"onStart",
"finishedOnStart",
"onStop",
"finishedOnStop",
"onDestroy",
"finishedOnDestroy");
transcript.clear();

Robolectric.buildActivity(MyActivity.class).setup().close();
assertThat(transcript)
.containsExactly(
"onCreate",
"finishedOnCreate",
"onStart",
"finishedOnStart",
"onPostCreate",
"finishedOnPostCreate",
"onResume",
"finishedOnResume",
"onPostResume",
"finishedOnPostResume",
"onPause",
"finishedOnPause",
"onStop",
"finishedOnStop",
"onDestroy",
"finishedOnDestroy");
}

@Test
public void close_tryWithResources_getsDestroyed() {
try (ActivityController<MyActivity> ignored =
Robolectric.buildActivity(MyActivity.class).setup()) {
// no-op
}
assertThat(transcript)
.containsExactly(
"onCreate",
"finishedOnCreate",
"onStart",
"finishedOnStart",
"onPostCreate",
"finishedOnPostCreate",
"onResume",
"finishedOnResume",
"onPostResume",
"finishedOnPostResume",
"onPause",
"finishedOnPause",
"onStop",
"finishedOnStop",
"onDestroy",
"finishedOnDestroy");
}

public static class MyActivity extends Activity {
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Expand Down
Expand Up @@ -44,7 +44,7 @@
*/
@SuppressWarnings("NewApi")
public class ActivityController<T extends Activity>
extends ComponentController<ActivityController<T>, T> {
extends ComponentController<ActivityController<T>, T> implements AutoCloseable {

enum LifecycleState {
INITIAL,
Expand Down Expand Up @@ -541,6 +541,38 @@ private Instrumentation getInstrumentation() {
return _component_.getInstrumentation();
}

/**
* Transitions the underlying Activity to the 'destroyed' state by progressing through the
* appropriate lifecycle events. It frees up any resources and makes the Activity eligible for GC.
*/
@Override
public void close() {

LifecycleState originalState = currentState;

switch (originalState) {
case INITIAL:
case DESTROYED:
return;
case RESUMED:
pause();
// fall through
case PAUSED:
// fall through
case RESTARTED:
// fall through
case STARTED:
stop();
// fall through
case STOPPED:
// fall through
case CREATED:
break;
}

destroy();
}

/** Accessor interface for android.app.Activity.NonConfigurationInstances's internals. */
@ForType(className = "android.app.Activity$NonConfigurationInstances")
interface _NonConfigurationInstances_ {
Expand Down

3 comments on commit feaded1

@seadowg
Copy link
Collaborator

@seadowg seadowg commented on feaded1 Feb 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does close need to be called to prevent Activity objects being leaked during tests?

@utzcoz
Copy link
Member

@utzcoz utzcoz commented on feaded1 Feb 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does close need to be called to prevent Activity objects being leaked during tests?

Hi @seadowg , could you file a new issue to discuss it? The discussion under commit can't be tracked and indexed well.

@seadowg
Copy link
Collaborator

@seadowg seadowg commented on feaded1 Feb 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! #7041

Please sign in to comment.