Mobile App Dev 2021W: Tutorial 7
This tutorial is due on March 23, 2021 via cuLearn. Please use this template for your solutions.
Tasks
- Compare this code with the code from Lecture 15. What functional differences are there between the apps (other than what messages are logged)? Be sure to rotate the app fully (a two-click process in the simulator) and use it in both orientations.
- What activity lifestyle events happen when you do the following with the app:
- launch the app
- terminate the app (from the app switcher)
- rotate the device (change device orientation)
- run another app?
- switch back to the app?
- What code is responsible for saving the app's state? When is this code called, relative to the main activity's lifecycle?
- What code is responsible for restoring the app's state? When is this code called, relative to the main activity's lifecycle?
- How is data organized in a bundle?
- How is data saved to a bundle?
- How is bundle data loaded?
- How persistent is bundle-stored data? How can this be verified?
- When rotating the app, currently it acts like the app has restarted even though the count is preserved. Change the app so that if the count is non-zero it will always display the right message. Your solution should avoid duplicate code.
Code
MainActivity.kt
package carleton.comp1601.tapdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.PersistableBundle
import android.util.Log
import android.view.View
import android.widget.TextView
class MainActivity : AppCompatActivity() {
private lateinit var myMessage: TextView
private var count = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TapDemo", "Created")
myMessage = findViewById(R.id.myMessage)
if (savedInstanceState != null) {
with(savedInstanceState) {
count = getInt("count")
}
} else {
count = 0
}
}
fun myButtonPressed(v: View) {
count++
myMessage.text = "You clicked $count times."
Log.d("TapDemo", "Button Pressed")
}
override fun onSaveInstanceState(outState: Bundle) {
outState.run {
putInt("count", count)
}
super.onSaveInstanceState(outState)
Log.d("TapDemo", "State saved")
}
override fun onDestroy() {
super.onDestroy()
Log.d("TapDemo", "Destroyed")
}
override fun onResume() {
super.onResume()
Log.d("TapDemo", "Resumed")
}
override fun onPause() {
super.onPause()
Log.d("TapDemo", "Paused")
}
override fun onStart() {
super.onStart()
Log.d("TapDemo", "Started")
}
override fun onStop() {
super.onStop()
Log.d("TapDemo", "Stopped")
}
override fun onRestart() {
super.onRestart()
Log.d("TapDemo", "Restarted")
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/TapDemo"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="myButtonPressed"
android:text="Tap me!"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
app:layout_constraintBottom_toTopOf="@+id/myMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/myMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="You haven't tapped yet."
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>