Mobile App Development 2021W Lecture 16

From Soma-notes

Video

Video from the lecture given on March 15, 2021 is now available.

Notes

Lecture 16
----------
Plan
 - Midterm
   - review solutions, class performance
   - interviews
 - upcoming tutorials and assignments
 - state in iOS and Android


Midterm average: 21.7 (67.83%)
Q1a 91.30%
Q1b 50.00%
Q1c 35.56%
Q1d 84.78%
Q1e 79.35%
Q1f 86.96%
Q1g 88.04%
 
Q2 83.70%
 
Q3 55.98%
 
Q4 27.17%
 
Q5a 91.30%
Q5b 85.87%
Q5c 73.33%
Q5d 64.67%
 
Q6a 89.13%
Q6b 73.91%
Q6c 92.39%
Q6d 94.77%
 
Q7a 80.00%
Q7b 65.56%
Q7c 76.11%
Q7d 68.48%

For interviews
 - I have some volunteers already (PM me if you wish to volunteer)
 - will randomly (and deliberately) select more

Interviews will be this week and next week
 - I'm going to put up a spreadsheet after class
 - add your name to the schedule where you want to talk
 - I will PM you if I want to interview you and you didn't volunteer
 - I'll open up times as necessary

Final exam
 - same format, just longer (2 hour exam)
 - will cover material from entire semester (so will include midterm
   material)
 - will have interviews after

Interviews are just 10 min discussing questions
 - ask about ones you got wrong
 - ones you got right
   - I want to understand your thinking, help you better understand
     the underlying concepts

If you do better on the final than the midterm, the final replaces the midterm
 - that's why it is cumulative


State in iOS and Android

in Android, activities have a "lifecycle"
 - created, destroyed, paused, stopped, resumed
 - https://developer.android.com/guide/components/activities/activity-lifecycle

Activities, once created, won't stay created
 - they can get messed with at arbitrary times

Mobile devices are constrained in CPU, memory, and battery
 - so OS must constantly manage resources
 - this means apps have to deal with their resources getting reclaimed at
   any time
 - also, in Android UI changes (like rotating the screen) are treated as
   a "restart" (i.e., kill the screen and start it again so it can use
   the new screen geometry)
 - so, your app has to manage state so it doesn't go back to zero

Note that in SwiftUI, this sort of state management is taken care of for us!

Code

The Mar10 Android code below is a modified version of the code from Lecture 15.

To create the iOS TapDemo, just make a new SwiftUI project and replace ContentView.swift with the code below.

TapDemo (iOS) ContentView.swift

//
//  ContentView.swift
//  Shared
//
//  Created by Anil Somayaji on 2021-03-15.
//

import SwiftUI

struct ContentView: View {
    @State var count = 0
    var body: some View {
        VStack{
            Button("Tap here!", action: onTapped)
                .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
            
            Text("You have tapped \(count) times.")
            .padding()
        }
    }
    func onTapped() {
        count = count + 1
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Mar10 (Android) MainActivity.kt

package carleton.comp1601.mar10

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
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("Tap Demo", "Created")

        myMessage = findViewById(R.id.myMessage)
    }

    override fun onResume() {
        super.onResume()
        Log.d("Tap Demo", "Resumed")
    }

    override fun onPause() {
        super.onPause()
        Log.d("Tap Demo", "Paused")
    }

    override fun onStart() {
        super.onStart()
        Log.d("Tap Demo", "Started")
    }

    override fun onStop() {
        super.onStop()
        Log.d("Tap Demo", "Stopped")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("Tap Demo", "Destroyed")
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("Tap Demo", "Restarted")
    }

    fun myButtonPressed(v: View) {
        count++
        myMessage.text = "You clicked $count times."
    }
}

Mar10 (Android) 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/Mar10"
    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>