Introduction to Scrum

Scrum reference card: http://scrumreferencecard.com/

About Scrum

Iteration: Sprint (15-30 days)
Incremental: each iteration produces shippable product with increment

Scrum Framework

Scrum Roles

Product Owner

Maximizing the return on investment (ROI) of the development effort

Make the product vision, customer related

Product backlog, release plan, accept/reject increment

Scrum Development Team

Cross-functional 7-9 members

Self-organizing, self-managing, Intensely collaborative, long-term stable team

Negotiates commitments with the Product Owner

Scrum Master

Helps resolve impediments

Support team about working environment, process, meeting,  promote best practice

Manage artifact, captures data

Enforce timeboxes

No management authority, no decision-making in meeting

Scrum Meetings

Scrum Flow

Sprint Planning Meeting

Attendees: PO + Team

Agenda:

– Select items in Product Backlog

– PO: Prioritize items

– Team: Estimate items

Output: Product Backlog Items (PBI) and sub Tasks

Sprint Planning Meeting output

Daily Scrum and Sprint Execution

Period: daily

Duration: 15 mins

Agenda: What was done previous day. What is issue. What will be done today.

Attendee: Team, may be Scrum Master, PO

Sprint Review Meeting

Attendee: PO, team

Agenda:

– Live demo

– PO: Review committed items, judge Accept/Reject

– PO: Review Product Backlog

Sprint Retrospective Meeting

Attendee: team

The goals are to gain a common understanding of multiple perspectives and to develop actions that will take the team to the next level.

Backlog Refinement Meeting

Agenda:

– Team provide tech info to PO to prioritize items

– Rough estimate size of item, big items (epics) will be split into user story

Scrum Artifacts

Product Backlog: PBI

Sprint Backlog: Sprint Tasks

Sprint Burndown chart

Product Burndown chart

Redirect printf to file

Work if you initiate program from shell

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  FILE *fp;

  printf("This will display on the screen.\n");

  if((fp=freopen("OUT", "w" ,stdout))==NULL) {
    printf("Cannot open file.\n");
    exit(1);
  }

  printf("This will be written to the file OUT.");

  fclose(fp);

  return 0;
}

Android filesystem cheatsheet

More detail about Android Storage options is here.

Internal storage

  • Context.getCacheDir()   ->  /data/data/<app.package.name>/caches
  • Context.getFilesDir()  ->  /data/data/<app.package.name>/files
  • Context.getDir(<dir_name>,<mode>)   ->  /data/data/<app.package.name>/app_<dir_name>

External storage (internal sdcard & external sdcard)

  • Environment.getExternalStorageDirectory()   ->  /sdcard
  • Environment.getExternalStoragePublicDirectory(<type>)   ->  /sdcard/Music, /sdcard/DCIM
  • Context.getExternalFilesDir(null)  ->   /sdcard/Android/<app.package.name>/files
  • Context.getExternalFilesDir(<type>)   ->  /sdcard/Android/<app.package.name>/files/Pictures

Sorting collection in Java

Ref:
http://stackoverflow.com/questions/2784514/sort-arraylist-of-custom-objects-by-property
http://stackoverflow.com/questions/18441846/how-sort-a-arraylist-in-java

Code:


// This is your list
List<MyObject> myObjects= new ArrayList<MyObject>();
// add some items to this list ...

// This is how to sort this list
Collections.sort(myObjects, new Comparator<MyObject>() {
  @Override
  public int compare(MyObject obj1,MyObject obj2) {
    // add compare logic, and return result, for example:
    return obj1.propertyToCompare.compareTo(obj2.propertyToCompare);
  }
});

Joda Time cheat sheet

Get Joda Time here.

Get current time:

DateTime now = new DateTime();

Get current date at mid night:

DateTime startOfToday = new DateTime().withTimeAtStartOfDay();

Get duration between 2 times:

Duration duration = new Duration(dateTime1, dateTime2);

Compare 2 date time (date only):

DateTimeComparator comparator = DateTimeComparator.getDateOnlyInstance();

comparator.compare(dateTime1, dateTime2);

Get DateTime at specific moment (2014 Oct 22, 23h 35m 59s)

DateTime specificMoment = new DateTime(2014,10,22,23,35,59,0);

Get DateTime from String, see detail format:

DateTimeFormatter formatter = DateTimeFormat.forPattern(“yyyyMMdd”);

DateTime dateTime =formatter.parseDateTime(“20141022”);

Get readable string from DateTime, see detail format:

DateTimeFormatter formatter = DateTimeFormat.forPattern(“yyyyMMdd”);

String readableDate = dateTime.toString(formatter);

Shift back DateTime to some days:

DateTime yesterday = new DateTime().minusDays(1);

Android Fragment quick start

Step 1: Create activity layout

Name it: test_activity.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/fragment_container</span>"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/white" >
</FrameLayout>

Note the id of fragment container (@+id/fragment_container). All fragments will be inflate to this id.

Step 2: Create fragments layout

We name it: test_fragment.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" >

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Fragment sample" />

</RelativeLayout>

This is a fragment, in which there is a TextView.

Step 3: Fragment code

Create class and extend android.support.v4.app.Fragment (or android.app.Fragment).

public class TestFragment extends Fragment {

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.test_fragment, container, false);
    return v;
  }
}

onCreateView() is where we configure the layout of fragment (can treat it like Activity.onCreate())
In it, we inflate the layout with template from frag_practice.xml created above.

Step 4: Activity code

Create class and extend android.support.v4.app.FragmentActivity (or android.app.FragmentActivity).
public class TestActitivity extends FragmentActivity {

public class TestActitivity extends FragmentActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
    setContentView(R.layout.test_activity);

    switchToFragment(new TestFragment());
  }

  void switchToFragment(Fragment newFrag) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment_container, newFrag);
    transaction.commit();
  }

}

Data storage in Android filesystem

In Android OS, application can have many options to store local data (offline, in filesystem). They are:

Shared Preferences

Application aspect:

  • Used to store primitive data (e.g. int, boolean, String…)
  • Key-value pairs. For example:
    • “address” -> “123 Wall Street”
    • “id” -> 132
    • “isPaid” -> true
  • Can’t be accessed by other apps.
  • Will be removed when user uninstall app.
  • How to use

Filesystem aspect:

  • All data is stored in XML files, located at:
    • /data/data/<app.package.name>/shared_prefs/*
  • Can be accessed by user with root privilege.

Internal Storage

Application aspect:

  • Used to store normal files/folders
  • Can’t be accessed by other apps.
  • Will be removed when user uninstall app.
  • How to use
    • Context.openFileInput() return FileInputStream
    • Context.openFileOutput() return FileOutputStream
    • read(), write(), close() as *InputStream

Filesystem aspect:

  • Data is stored as normal file, at:
    • /data/data/<app.package.name>/files/
  • Some APIs:
    • Context.getCacheDir() return File point to /data/data/<app.package.name>/caches
    • Context.getFilesDir() return File point to /data/data/<app.package.name>/files
    • Context.getDir(<dir_name>,<mode>) create and return File point to /data/data/<app.package.name>/app_<dir_name>

External Storage

There are 2 types:

  • Removable storage: like external SD Card (you can physical remove it).
  • Non-removable: on-board flash memory (NAND/NOR), partitioned to be used as external storage.

One device can have multi external storages (1 is called primary). From now on, assume that we use primary, and located at /sdcard.

Also pay attention to these permissions:

  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.READ_EXTERNAL_STORAGE

Application aspect:

  • Used to store normal files/folders
  • Can be accessed by other apps.
  • How to use

Filesystem aspect:

  • Public storage (system-wide access, won’t be deleted when uninstalling):
    • Environment.getExternalStorageDirectory() return File point to the top-level primary external storage directory. i.e. /sdcard. May leave garbage to user, should not use.
    • Environment.getExternalStoragePublicDirectory(<type>) return File point to some common public folder. i.e. /sdcard/Music, /sdcard/DCIM
  • Private storage API (app access, will be deleted when uninstalling):
    • Context.getExternalFilesDir(null) to get top-level dir. i.e. /sdcard/Android/<app.package.name>/files
    • Context.getExternalFilesDir(<type>) return File point to some common app-private folder. i.e. /sdcard/Android/<app.package.name>/files/Pictures

Database

TBD

Get Android app name

Normally, ADT eclipse auto create string app_name in your strings.xml. And set it in manifest like this:

<application
  android:name=".MyApp"
  android:icon="@drawable/ic_launcher_icon"
  android:label="@string/app_name"
  android:debuggable="true">

Method 1: If that, you can easily get app name by:

String applicationName = getResources().getString(R.string.app_name);

Method 2: But if you didn’t specify it in resource xml, you can also get app name by:

int stringId = context.getApplicationInfo().labelRes;
return context.getString(stringId);