+ - 0:00:00
Notes for current slide
Notes for next slide

The Whole Toolkit Part II

Lauren Bricker

CSE 340 Spring 2021

Slide 1 of 35

Today's goals

  • Cleanup of slide decks (PPS, Whole Toolkit Part I)
  • Clarifications
  • Continuing The "whole toolkit"
    • Recount how we get input from the user (part 1) and produce output for the user (part 2)
    • How to store application specific data

Administrivia

  • ColorPicker Midpoint (video) Due Thursday 10pm
Slide 2 of 35

Clarification 1

There were some constructive criticisms to address from the the midquarter evaluation.

  1. Learning objectives not clearly laid out
    • Learning objectives for each day are on the Schedule page
    • Outline gives finer grained details on what will be in the class.
  2. Creative aspects to assignments (like 154)
    • We try to have a creative/design piece for each assignment
    • Goal for next year: having a creative final project in this class
  3. Time management -
    • This is something readily admit I am working on and will try to be better about
  4. Include activity instructions on a slide
    • Great suggestion! We'll try to remember this.
Slide 3 of 35

Clarification 2

From last time: Which of the following does NOT generate an event?

A. Pressing the CTRL key
B. Pressing the A key
C. Moving your finger on the phone screen
D. Clicking a mouse button (on a computer)

A subtlety this question does not capture:

Each key press is described by a sequence of key events. A key press starts with a key event with ACTION_DOWN. If the key is held sufficiently long that it repeats, then the initial down is followed additional key events with ACTION_DOWN and a non-zero value for getRepeatCount(). The last key event is a ACTION_UP for the key up.

From the Android KeyEvent page

Slide 4 of 35

The Whole Toolkit Architecture

  • Input
    • Input models (events)
    • Event dispatch
    • Event handling (state machine)
    • Callbacks to application
  • Output
    • Interactor Hierarchy design & use
    • Drawing models (onDraw())
    • Layout (onLayout() or XML)
    • Damage and redraw process
  • Storage
    • Bundles
    • Shared Preferences
Slide 5 of 35

Interactor Hierarchy

0: Drawing Canvas
1: CircleA, Green
2: LineB, Orange
3: LineA, Black
4: PointA, Blue
5: PointB, Black
A picture of lines and circles
Slide 6 of 35

Core Toolkit Architecture

damage is a bit kept on each view. If state changes, damage becomes true

If there is damage do

  • layout (may change)
    • position
    • size
  • redraw
0: Drawing Canvas
1: CircleA, Green
2: LineB, Orange
3: LineA, Black
4: PointA, Blue
5: PointB, Black

A picture of lines and circles

Slide 7 of 35

Core Toolkit Architecture

damage is a bit kept on each view. If state changes, damage becomes true

If there is damage do

  • layout (may change)
    • position
    • size
  • redraw

Component Developer

  • May need to implement onMeasure() and onLayout() (if a container)
  • Will always implement onDraw() but never call it (call invalidate() instead)
Slide 8 of 35

View Update: Damage/Redraw

How does the toolkit know what to redraw?

What causes damage?

Slide 9 of 35

concrete example on next slide

View Update: Damage/Redraw

What should be redrawn?

google doc with scrollbar

Slide 10 of 35

View Update: Damage/Redraw

What should be redrawn?

google doc with scrollbar

Slide 11 of 35

View Update: Damage/Redraw

What should be redrawn?

google doc with scrollbar

Slide 12 of 35

View Update: Damage/Redraw

How does the toolkit know what to redraw?

What causes damage?

Slide 13 of 35

View Update: Damage/Redraw

How does the toolkit know what to redraw?

What causes damage?

  • Window hidden and re-exposed
  • Resizing
  • Redrawing
  • Reacting to system or other events
  • others???
Slide 14 of 35

View Update: Damage/Redraw

Naive approach to redraw

pic of original screen and changed screen

Slide 15 of 35

View Update: Damage/Redraw

Naive approach to redraw

pic of original screen and changed screen

  • Can be slow (redrawing everything unecessary)
  • Can cause flickering
    • double buffering is better,
    • hence the 'Canvas' abstraction or equivalent
    • can then switch which FB is displayed (very fast)
Slide 15 of 35

TODO ADD pic like this using divs?


View Update: Damage/Redraw

Naive approach to redraw - redraw the entire screen

pic of original screen and changed screen

More efficient: calculate only the region necessary

pic with double buffering included

View Update: Damage/Redraw

Naive approach to redraw - redraw the entire screen

pic of original screen and changed screen

More efficient: calculate only the region necessary

pic with double buffering included

Never just draw: Why not?

Slide 16 of 35

View Update: Damage/Redraw

Naive approach to redraw - redraw the entire screen

pic of original screen and changed screen

More efficient: calculate only the region necessary

pic with double buffering included

Never just draw: Why not?

  • Update state
  • Report damage (by calling 'repaint())
  • Wait for toolkit to request redraw (also works if damage comes from elsewhere)
  • How does it generalize to any cause of damage (always need state!!)
Slide 17 of 35

View Update: Damage/Redraw

How does the toolkit know what to redraw?

  • Let the component report: Damage/Redraw invoked by invalidate() or equivalent
Slide 18 of 35

View Update: Damage/Redraw

How does the toolkit know what to redraw?

  • Let the component report (invalidate()) NOTE we are not calling onDraw() directly (important for your assignment)
  • Aggregate
  • Usually calculate bounding box
Slide 19 of 35

View Update: Draw/Redraw

Virtual device abstraction provided by windowing system

Component abstraction provided by toolkit

  • Enforced using clipping
  • Supported using coordinate system transformations

Drawing is recursive

  • Makes it possible for parent to decorate kids
  • Parent responsible for making kids think they are the center of the universe (translate)
  • Clipping: intersect parent and child, also handled by parent
Slide 20 of 35

Allows each program to (mostly) pretend that it has the screen (frame buffer) to itself

Allows each component to (mostly) pretend that it has the screen to itself

Core Toolkit Architecture

If damage do

  • layout (may change)
    • position
    • size
  • do redraw
    • Union of damage (any of those can cause it) used to trigger redraw of anything inside that union
    • Drawing + clipping – standard drawing order, but only for things damaged; clipped to damage region
    • Clear damage
Slide 21 of 35

The Whole Toolkit Architecture

  • Input
    • Input models (events)
    • Event dispatch
    • Event handling (state machine)
    • Callbacks to application
  • Output
    • Interactor Hierarchy design & use
    • Drawing models (onDraw())
    • Layout (onLayout() or XML)
    • Damage and redraw process
  • Storage
    • Bundles
    • Shared Preferences
Slide 22 of 35

So you got lots of apps..

And they all want to use tons of memory, but they don't need that memory all the time.

  • Android: You get no/minimal memory when you're not actively being used.
  • Apps: But then how do we remember stuff when we are being used if we can't save it in memory
  • Android: Use this bundle

(In truth the app could write/read its state to disk whenever it is being closed/opened but that is time consuming and would delay the OS launching new things)

Slide 23 of 35

What is a Bundle?

  • First what happens when the user closes the application? Does it die?
    • No!
Slide 24 of 35

What is a Bundle?

  • First what happens when the user closes the application? Does it die? No
  • Where does it go then?
    • Think about it as hibernation
    • All of it's memory is cleared, so all of your variables are GONE 😲.
    • But Android lets you save some variables to a bundle right before your memory is cleared, and gives you your bundle back when you get the memory space back.

Bundle documentation

Slide 25 of 35

What is a Bundle?

  • First what happens when the user closes the application? Does it die? No
  • Where does it go then? Stored by Android OS
  • What's in the bundle?
    • You decide, entirely up to the application developer (you).
    • Values are mapped to unique KEYS (for set/retrieve)
  • Bundle is destroyed if the user force quits the app/phone is turned off.
Slide 26 of 35

Bundles & Code

  • Bundle management is occuring at the activity layer, not to be confused with any individual view.
  • When the user closes the app, right before it closes and its memory is cleared, Android invokes onSaveInstanceState(Bundle outState) on the activity, providing a reference to the activity for the app to save values into.
  • Then when the user opens the app again, Android invokes onRestoreInstanceState(Bundle savedInstanceState) returning the same bundle from earlier.
  • You can think of the bundle as a Map<String, Object> that only supports certain types of objects (they must be Serializable which includes all primitives and String)

(Read more here)

Slide 27 of 35

Bundles: Code Example

public abstract class MainActivity extends AppCompatActivity {
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("OUR_KEY", "bundles? bundles!!!");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String whatWeSaved = savedInstanceState.getString("OUR_KEY");
// whatWeSaved would contain "bundles? bundles!!!"
}
}
Slide 28 of 35

Bundle in Accessibility

Bundles can be used to comunicate when switching activities.

Example in Ask For Help - in ChooseRequestsActivity

// Instance variable declaration
private Bundle mMessageInfo;
// Instance variable initialization (in setVariables called by onCreate)
mMessageInfo = new Bundle();
// Setting key/value pairs
mMessageInfo.putString("last_button_pressed", "none");
// Switching activities
Intent intent = new Intent(this, ChooseContactGroupsActivity.class);
mMessageInfo.remove("last_button_pressed");
String request = ((TextView)view).getText().toString();
mMessageInfo.putString("last_button_pressed", request);
// Attaching the bundle to the intent
intent.putExtras(mMessageInfo);
startActivity(intent);
Slide 29 of 35

Bundle in Accessibility

Bundles can be used to comunicate when switching activities.

Example in Ask For Help - in ChooseContactsActivity

// Instance variable declaration
private Bundle mMessageInfo;
// Instance variable initialization (in setVariables called by onCreate)
mMessageInfo = getIntent().getExtras();
// Add things to the bundle in addNumbersToBundle and textPeople
mMessageInfo.putString("contact" + (ii + 1), contactsAsString);
// Get information from the bundle
String textBody = mMessageInfo.getString("last_button_pressed");
String numbers = "smsto:" + mMessageInfo.getString("contact" + contactID);
Slide 30 of 35

Shared Preferences

  • Bundle data is transient - it will go away if the app is completely unloaded from memory.
    • Typically small amounts of data.
    • Used to share information between activities.
  • Shared preferences are saved in internal storage space on the phone.
    • Also stored in Key Value pairs

SharedPreferences documentation

Slide 31 of 35

Shared Preferences

To see what is in your shared preferences

  1. start the Device File Explorer (View->Tool windows->Device File Explorer)
  2. Use the toggles to open up the following folders
data
data
<packagename> for your app, such as cse340.askforhelp
shared_prefs
<packagename>.PREFERENCES.xml
Slide 32 of 35

Shared Preferences

Creating the Shared Preferences File

protected SharedPreferences getPrefs() {
if ( mSharedPreferences == null ) {
try {
Context context = getApplicationContext();
mSharedPreferences = context.getSharedPreferences(context.getPackageName() + ".PREFERENCES",
Context.MODE_PRIVATE);
} catch (Exception e) {
//failed to edit shared preferences file
showToast(R.string.shared_pref_error);
}
}
return mSharedPreferences;
}
Slide 33 of 35

Shared Preferences

Saving to/restoring from the Shared Preferences file.

// setting data
SharedPreferences.Editor editor = getPrefs().edit();
editor.putBoolean("mLocationOn", true);
editor.putInt("group_selected", mWhichGroup);
editor.putString("contactGroup" + (ii + 1), contactGroup);
editor.putStringSet("contact_numbers" + (ii + 1), mNumbers.get(ii));
editor.apply(); // have to force the write.
// getting data, the last parameter is the default.
mLocationOn = getPrefs().getBoolean("mLocationOn", true);
mWhichGroup = getPrefs().getInt("group_selected", 1);
String contactGroupName = getPrefs().getString("contactGroup" + (ii + 1), "");
Set<String> ids = getPrefs().getStringSet("contact_ids" + (ii + 1),
Slide 34 of 35

END OF DECK

Slide 35 of 35

Today's goals

  • Cleanup of slide decks (PPS, Whole Toolkit Part I)
  • Clarifications
  • Continuing The "whole toolkit"
    • Recount how we get input from the user (part 1) and produce output for the user (part 2)
    • How to store application specific data

Administrivia

  • ColorPicker Midpoint (video) Due Thursday 10pm
Slide 2 of 35
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
s Start & Stop the presentation timer
t Reset the presentation timer
?, h Toggle this help
Esc Back to slideshow