Android Programming The Big Nerd Ranch Guide by Bill Phillips, Chris Stewart, Kristin Marsicano (z-lib.org)

(gtxtreme123) #1

Rotation and Object Continuity


Rotation and Object Continuity


Now you are a good citizen, which is nice. Unfortunately, your app no longer handles rotation
correctly. Try playing the 69_ohm-loko sound and rotating the screen: The sound will stop abruptly. (If
it does not, make sure you have built and run the app with your recent onDestroy() implementation.)


Here is the problem: On rotation, the BeatBoxActivity is destroyed. As this happens,
the FragmentManager destroys your BeatBoxFragment, too. In doing that, it calls
BeatBoxFragment’s waning lifecycle methods: onPause(), onStop(), and onDestroy(). In
BeatBoxFragment.onDestroy(), you call BeatBox.release(), which releases the SoundPool and
stops sound playback.


You have seen how Activity and Fragment instances die on rotation before, and you have solved these
issues using onSaveInstanceState(Bundle). However, that solution will not work this time, because it
relies on saving data out and restoring it using Parcelable data inside a Bundle.


Parcelable, like Serializable, is an API for saving an object out to a stream of bytes. Objects may
elect to implement the Parcelable interface if they are what we will call “stashable” here. Objects
are stashed in Java by putting them in a Bundle, by marking them Serializable so that they can be
serialized, or by implementing the Parcelable interface. Whichever way you do it, the same idea
applies: You should not be using any of these tools unless your object is stashable.


To illustrate what we mean by “stashable,” imagine watching a television program with a friend. You
could write down the channel you are watching, the volume level, and even the TV you are watching
the program on. Once you do that, even if a fire alarm goes off and the power goes out, you can look at
what you wrote down and get back to watching TV just like you were before.


So the configuration of your TV watching time is stashable. The time you spend watching TV is not,
though: Once the fire alarm goes off and the power goes out, that session is gone. You can return and
create a new session just like it, but you will experience an interruption no matter what you do. So the
session is not stashable.


Some parts of BeatBox are stashable – everything contained in Sound, for example. But SoundPool
is more like your TV watching session. Yes, you can create a new SoundPool that has all the same
sounds as an older one. You can even start playing again right where you left off. But you will always
experience a brief interruption, no matter what you do. That means that SoundPool is not stashable.


Non-stashability tends to be contagious. If a non-stashable object is critical to another object’s mission,
that other object is probably not stashable, either. Here, BeatBox has the same mission as SoundPool: to
play back sounds. Therefore, ipso facto, Q.E.D.: BeatBox is not stashable. (Sorry.)


The regular savedInstanceState mechanism preserves stashable data for you, but BeatBox is not
stashable. You need your BeatBox instance to be continuously available as your Activity is created
and destroyed.


What to do?

Free download pdf