PROCESSES & LIFECYCLES
July 12, 2010
- which processes to kill and which to keep?
- each process is in an importance hierarchy
- position on hierarchy is based on the components and state of the components in the process
- 5 levels in hierarchy
- FOREGROUND PROCESS
- running activity user interacting with -> onResume()
- hosts service bound to activity user interacting with
- has service executing one of its lifecycle callbacks ->onCreate(), onStart(), onDestroy()
- has broadcast receiver executing onReceive() method
- VISIBLE PROCESS
- no foregound components but still affects what user sees on screen
- hosts an activity visible to user but not in foreground -> onPause()
- hosts a service bound to a visible activity
- SERVICE PROCESS
- running a service started by startService() but doesn’t qualify as one of the above
- BACKGROUND PROCESS
- activity not visible -> onStop()
- LRU: Least Recently Used
- EMPTY PROCESS
- Holds no active components
- mostly for cache purposes to improve performance
Component Lifecycles
July 12, 2010
- ACTIVITY
- 3 states:
- Active/Running – foreground on the screen (top of activity stack for the current task)
- Paused – lost focus but still visible to the user i.e another transparent of partial window activity on top
- Stopped – completely obscured by another activity
SAVING ACTIVITY STATE
- Capture state before activity is killed by system by implementing onSaveInstanceState()
- Android calls it before onPause() and passes it a bundle object
- record in the object the state as name-value pairs
- when activity is restarted the bundle is passed both in onCreate() and onRestoreInstanceState() methods for you to rebuild the state
- only save in onSaveInstanceState() transient data
- persistent data is save in the onPause() method
- 3 states:
- SERVICE LIFECYCLE
- Two ways services are used:
- Start and allow to run until someone stops it or stops itself -> Context.startService, Context.stopService or Service.stopSelf or Service.stopSelfResult
- Operate programatically via interface which clients use to establish a connection via Context.bindService, Context.unbindService

- Two ways services are used:
- BROADCAST RECEIVER LIFECYCLE
- Single callback method void onReceive(Context curContext, Intent broadcastMsg)
- when response to a broadcast message is time consuming DONT SPAWN a new Background THREAD
- instead let onReceive START A SERVICE to do the job so that the system know’s there’s still active work being done in the process
Processes and Threads
July 9, 2010
By default all components run in a single process and thread
PROCESSES
- Controlled in the manifest file “process” attribute of component elements
- allows use of individual processes and/or shared processes
- Android may shut down processes if memory is too low, basis is on relative importance to user (component status)
THREADS
- Single process or not, the thread hosting activity (UI) should not host time consuming operations
- Spawn threads to maintain good UI performance
- Std. Java threads with convenience classes
- Looper – running a message loop within a thread
- Handler – processing messages
- HandlerThread – set up a thread with a message loop
REMOTE PROCEDURE CALLS
- Method called locally but executed remotely (in another process) and results returned back to caller
- RPC interface includes Methods ONLY - default synchronous execution
- Typically managed by a Service
THREAD SAFE METHODS
- in few contexts where the methods you implement may be called from more than one thread ex. RPC, ContentPovider
- Ref Java Thread Safety
Application Components
July 9, 2010
Components:
- ACTIVITIES
- Visual UI for one focused endeavor the user can undertake
- each activity is given a default window to draw in
- can also make use of additional windows ex. pop up dialogs
- visual content of window is provided by a HIERARCHY OF VIEWS
- VIEW:
- controls a particular rectangular space within the window ex. buttons, text field
- SERVICES
- No UI, runs in the background for an indefinite period of time
- bind to / connect to :: start the service / ongoing service and communicate with i through an INTERFACE that the service Exposes
- Often spawns another THREAD for time -consuming tasks ex music play back
- BROADCAST RECEIVERS:
- No UI but may start an activity or use NotificationManager
- receive and react o broadcast announcements ex timezone changes, low battery power
- CONTENT PROVIDERS:
- make a specific set of the app’s data available to other apps
- data may be stored in file system, SQLite DB, etc
- Apps dont call methods directly! they instead use a ContentResolver object and call its methods
ACTIVATING COMPONENTS
Intents – Asynchronous Messages -> Object holding content of message
- ACTIVITY
- Launch or instruct to do something via Intent Object to context.startActivity() or Activity.startActivityFor Result()
- returns Intent Object passed into onActivityResult()
- getIntent() for initial Intent
- onNewIntent() for subsequent intents
- Launch or instruct to do something via Intent Object to context.startActivity() or Activity.startActivityFor Result()
- SERVICE
- Context.startService() passing IntentObject into onStart()
- Context.bindService() passing IntentObject into onBind()
- BROADCASE RECEIVERS
- Context.sendBroadcast()
- Context.sendOrderedBroadcast()
- Context.sendStickyBroadcast() all 3 passing IO to onReceive()
- CONTENT PROVIDERS
- activated when targeted by a request from a ContentResolver
SHUTTING DOWN COMPONENTS
- ACTIVITY – call finish() or finishActivity() fro another activity it started
- SERVICE – call stopSelf() or Context.stopService()
- BROADCAST RECEIVER – only active while responding to a broadcast message
- CONTENT PROVIDERS – only active while responding to request from ContentResolver
Threading – part 2
September 16, 2009
Please see my previous post
Mutual Exclusion / Critical Section aka Mutex
- “Mutual exclusion” — scheduling threads so that only one thread at a time executes a critical section of code. Essentially, keeping the threads from interfering with each other. Avoid reader/writer and writer/writer conflicts on shared memory between threads.
- Critical section — a section of code that manipulates shared memory, and so must not be run by multiple threads at the same time.
- “Race condition” — a piece of code with unaddressed concurrency problems, and so depending on how the threads happen to schedule each time, you may get different output.
Coordination
- “Coordination” — managing the schedules of multiple threads so they can start/pause/etc. to mesh their schedules.
- Typically this centers on handing information from one thread to another, or signaling one thread that another thread has finished doing something.
- We will use join() and Semaphores for this
Example:
class Pair {
private int a, b;
public Pair()
{
a = 0;
b = 0;
}
// Returns the sum of a and b. (reader)
public int sum()
{
return(a+b);
}
// Increments both a and b. (writer)
public void inc()
{
a++;
b++;
}
}
Reader/Writer conflict:
- thread1 runs inc() while thread2 runs sum() on the same object.
- In that case, the sum() thread could get an incorrect value if the inc() is halfway done.
- In part, this happens because the lines of inc() and sum() interleave
- Note that this is only a problem if the threads are executing against the same object so they both touch the same memory.
Writer/Writer conflict:
- thread1 runs inc() while thread2 runs inc() on the same object.
- The two inc()’s can interleave to mess up the object state
Object Lock + Synchronized Method
- In Java, every object has a “lock”
- A “synchronized” method respects the lock of the receiver object.
- For a thread to execute a synchronized method against a receiver, it first obtains the lock of the receiver. The lock is released when the method exits
- If the lock is already held by another thread, the calling thread blocks (efficiently) waiting for the other thread to exit and so make the lock available.
- In this way, multiple threads, in effect, take turns on who can execute against the receiver — mutual exclusion.
- If a method is not synchronized, it will ignore the lock and just go ahead.
Example:
In our example above, we solve the race conditions by declaring the critical section as synchronized — they respect the lock on the receiver object.
public synchronized int sum()
{
return(a+b);
}
// Increments both a and b. (writer)
public synchronized void inc()
{
a++;
b++;
}
Synchronized(obj) {…} Block
- A variant of the synchronized method.
- Acquire/Release lock for a specific object.
- Allows us to specify exactly where to lock, and with what object
- A little slower, a little less readable
Threading
September 10, 2009
Knowledge of Java Threads is a prerequisite before building any “beyond basics” app ..um game!
I’ll try and touch on some basic thread fundamentals:
Threads in Java are a little easier to deal with than other languages as the VM keeps track of all the threads and schedules them to get CPU time.
A Thread object is just a regular Java object and is essentially a token which represents a thread of control in the VM.
We send messages to the Thread object — the VM interprets these and does the appropriate operations on the underlying thread of control in the VM
Current Thread:
The thread currently executing statements, has its own stack separate from other threads.
int i = 6;
int sum = 7 + 12; // regular computation
Thread me = Thread.currentThread(); // “me” is the Thread object that represents our thread of control (the thread that computed the sum above)
How To Use a Separate Thread:
- Subclass off Thread and implement override the run() method
- Create an instance of your Thread subclass. It is not running yet, so you can set things up
- Send the thread object the start() message — at this point the VM can allocate a real thread of control, and schedule it to execute the Thread object’s run() method. Do not call run() directly — that’s a classic coding error and it does something unintuitive
- A thread of control begins executing the run() method of the Thread object. The JVM can time-slice between the various threads, running each for a little while.
- Eventually, the thread of control finishes/exits the run() method
How to Wait for Another Worker Thread to Complete its run():
Sending the join() message to the worker thread object — worker.join() — causes the current running thread to block efficiently until worker finishes its run
We must handle the InterruptedException that join() may throw. Java will break us out of the join if we are interrupted by another thread, so really there are two ways to get out of a join() — the other thread finishes, or we are interrupted. In most cases, we will handle InterruptedException by doing nothing.
// start a thread
Thread t = new …
t.start(); // at this point, two threads may be running — me and t
// wait for t to complete its run
try {
t.join();
} catch (InterruptedException ignored) {}
// now t is done (or we were interrupted)
Alternate Way to Use a Separate Thread:
Instead of creating a Thread object, you can implement the Runnable interface, which defines a single method prototype: public void run();
Run() defines the code you want to run, and this gives you flexibility to execute the code in different ways
You can pass a Runnable to a Thread in its constructor, and it will run it.
static void demoRunnable() {
// Make a runnable.
Runnable runnable = new Runnable() {
public void run() {
System.out.println(“Yay Runnable!”);
}
};
// Make a thread on the runnable and run it.
Thread thread = new Thread(runnable);
thread.start();
}
My next article will deal with concurrency race conditions that may arise as a result of implementing multiple number of threads in an app and how to resolve them