Está en la página 1de 44

Android Application Model

Component Model for Mobile Applications

Dominik Gruntz University of Applied Sciences Northwestern Switzerland, Brugg-Windisch 8925

Introduction
Android Experience > Android Core Libraries (together with Noser) > Android Projects HikeTracker [swisstopo] SyncML Addressbook Synchronizer [Swisscom] Component Software Experience > Responsible for the Java Chapter of the Book on "Component Software"

AGENDA
Android Components > Activities Intents & Filters Task / Application Lifecycle Processes and Threads > Services > Content Providers

Android Software Stack


> Java

> C/C++

> Kernel

Android Components
Activity [User Interaction] > UI component typically corresponding to a screen E.g. Contacts: 3 activities: View contacts, Send message, Edit contact Service [Service Provider] > Background process without UI (e.g. mp3 player) Messages can be sent from and to a service [Data Provider] Content Provider > Enables applications to share data E.g. Contacts are provided to all applications [System Event Listener] Broadcast Receiver > Responds to external events, can wake up your process Phone rings, network activity established, time controlled

Activity
Activity is usually a single screen > Implemented as a single class extending Activity > Displays user interface controls (views) > Reacts on user input / events An application typically consists of several activities > Each screen is typically implemented by one activity > Moving to the next screen means starting a new activity > An activity may return a result to the previous activity

Intents
Intent > Intents are used to move from activity to activity > Intent describes what the application wants to do > Consists of Action to be performed (MAIN / VIEW / EDIT / PICK / DELETE / ) Categories Data to act on (URI) Extras (primitives / primitives[] / Strings / Serializable) Flags Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.fhnw.ch")); Intent intent = new Intent(Intent.ACTION_EDIT); intent.setData(Uri.parse("content://contacts/people/1"));

Intents
Intent Invocation > Launch new activity (without receiving a result)
startActivity(intent);

> Launch new activity and expect result


startActivityForResult(intent, requestCode)

When activity exits, onActivityResult method is called with given requestCode (int > 0)
onActivityResult(int requestCode, int resultCode, Intent result)

Intents
Intent Specification > Intents define the interface between components > Intent repository on www.openintents.org

10

Intents and Intent Filters


Intent Filters > Description of what intents an activity can handle > Activities publish their intent filters in a manifest file
<intent-filter android:priority="0"> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="geo"/> </intent-filter>

> Upon invocation of startActivity(intent) the system looks at the intent filters of all installed applications

11

Android Component Model


Component Software > Activities can reuse functionality from other components simply by making a request in form of an Intent > Activities can be replaced at any time by a new Activity with an equivalent Intent Filter
Intent i = new Intent( "com.google.android.radar.SHOW_RADAR"); i.putExtra("latitude", 47.6f); i.putExtra("longitude", 8.23f); startActivity(i);

12

Android Component Model


Android Market: Software Libraries > Radar > HighScore List > Text-To-Speech Library > Log Collector Includes standalone app

13

Android Component Model


Packaging: APK File (Android Package) > Collection of components > Components share a set of resources Preferences, Database, File space > Components share a Linux process By default, one process per APK > APKs are isolated Communication via Intents or AIDL > Every component has a managed lifecycle

APK Process
Activity Activity

Content Provider

Service

14

Task / Application / Process


Task (what users know as applications) > Collection of related activities > Capable of spanning multiple processes > Associated with its own UI history stack
Process
Activity Activity

Process
Activity Activity

APK
Content Provider

APK
Content Provider

Service

Service

15

Task / Application / Process


Tasks > Processes are started & stopped as needed > Processes may be killed to reclaim resources > Upon Invocation of another activity, the view state can be saved

Home

Inbox

Details

Browse

Maps

> Comparable with EJB's stateful session beans (SFSB) > Each Android component has a managed lifecycle

16

Activity Life Cycle


New

Active / Running > Activity is in foreground > Activity has focus Paused > Still visible, partially overlaid > Focus lost Stopped > Activity is not visible Destroyed > Activity was terminated or killed

onRestart() onStart() onResume()

onCreate() onStart() [onRestoreInstanceState()] onResume()


Running

onSaveInstanceState() onPause()

onResume()

onStop()
Stopped Paused

onDestroy() onPause() onStop() onDestroy() <<kill>>


Destroyed

<<kill>>

17

Activity Life Cycle (1/2)


onCreate > Called when activity is first created (with null parameter) or when activity was killed (called with a bundle) > Initialization of views onRestart > Called when activity was stopped only onStart > Activity becomes visible to user, animations could be started onRestoreInstanceState > Restore view state onResume > New activity is visible, TOS, camera might be used here

18

Activity Life Cycle (2/2)


onSaveInstanceState > Save UI state of a complex dialog
=> onCreate => onRestoreInstanceState

> If application is explicitly finished, this method is not called > Called before or after onPause onPause > Activity no longer TOS but still visible > New activity is not started until onPause returns onStop > Activity no longer visible onDestroy > Release resources; it is not guaranteed that this method is called

19

Activity Life Cycle Samples (1/2)


Open Child Activity > onCreate(null) -> onStart -> onResume() -> [Open Child Activity] > onSaveInstanceState() -> onPause() -> onStop() -> [Close Child Activity] > onRestart() -> onStart() -> onResume() Transparent View > onCreate(null) -> onStart -> onResume() -> [Open Transparent View] > onSaveInstanceState() -> onPause() -> [Close Transparent View] > onResume() Turn Display > onCreate(null) -> onStart -> onResume() -> [Turn Display] > onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()

20

Activity Life Cycle Samples (2/2)


Home > onCreate(null) -> onStart -> onResume() -> [Home Button] > onSaveInstanceState() -> onPause() -> onStop() -> [Start App] > onRestart() -> onStart() -> onResume() Phone Call Interrupt > onCreate(null) -> onStart -> onResume() -> [Phone Call] > onSaveInstanceState() -> onPause() -> onStop() -> [Hang Up or press Back] > onRestart() -> onStart() -> onResume()

21

Process / Thread
Threading Overview > Each process has one thread (by default) => Single Threaded Model Threads and Loopers > Each thread has a Looper to handle a message queue > Events from all components are interleaved into the looper/Queue

APK

Process

Thread

Looper
1 1

Handler

Message Queue

22

Process / Thread
ActivityThread > Manages the main thread in an application process > Calls Looper.loop Looper.loop
while(true){ Message m=queue.next(); // may block if(m!=null){ m.target.dispatchMessage(m); m.recycle(); } }
Activity

APK Process
Thread Looper Activity Message Queue UI Events Local Service Calls

Intent Recvr

System Events

23

Process / Thread
Location Update in HikeTracker (onLocationChanged)

24

Process / Thread
Activity Result call-back (onActivityResult)

25

Process / Thread
Inactive Activities > If an activity does not consume events, the system assumes that the activity has a problem > AndroidNotResponding is shown No reaction to UI event within 5Sec No reaction to BroadcastEvent within 10Sec

26

Dealing with Threads


button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new Thread() { @Override public void run() { input1.setText("" + counter1++); } }.start(); } });

checkRoot > Compares current thread with thread which created the view

27

Dealing with Threads


Activity.runOnUiThread(Runnable) > Runs the specified action on the UI thread, i.e. the action is posted into the event queue of the UI thread Handler > Associated with a thread and its message queue > Used to add messages in the message queue sendMessage postRunnable sendMessageAtFrontOfQueue postAtFrontOfQueue sendMessageAtTime postAtTime sendMessageDelayed postDelayed > Used to handle the request (called by associated thread)

28

Android Process & Security


Security Model > Each application runs in its own process Has its own unique Linux User ID Each application has access to its own data
USER root radio app_2 app_14 app_8 app_21 app_0 app_3 PID 23 87 92 120 158 160 175 183 PPID 1 23 23 23 23 23 23 23 VSIZE RSS WCHAN PC 69508 18668 c008be9c afe0b874 100940 16320 ffffffff afe0c824 101792 17900 ffffffff afe0c824 93772 11444 ffffffff afe0c824 100088 11860 ffffffff afe0c824 99740 13064 ffffffff afe0c824 90580 11116 ffffffff afe0c824 94784 12080 ffffffff afe0c824 NAME S zygote S com.android.phone S android.process.acore S com.google.process.gapps S com.android.mms S ch.fhnw.imvs.hello S com.android.alarmclock S android.process.media

> Other resources are only available by defined interfaces Services [exposes functionality] Content Provider [exposes data]

29

Android Processes
public class P1/P2 extends Activity { ... public void onStart(){ super.onStart(); Properties p = System.getProperties(); System.out.println("getProperties().id = " + System.identityHashCode(p)); System.out.println("getProperties().size() = " + p.size()); if(p.get("Android") == null){ p.put("Android", 0); } else { p.put("Android", ((Integer)p.get("Android"))+1); } System.out.println("P1/2: onStart " + p.get("Android")); System.out.println("getProperties().size() = " + p.size()); } }

30

Processes: Output
Output of Activity P1
INFO/System.out(12470): INFO/System.out(12470): INFO/System.out(12470): INFO/System.out(12470): getProperties().id = 1073834816 getProperties().size() = 37 P1: onStart 0 getProperties().size() = 38

Output of Activity P2
INFO/System.out(12504): INFO/System.out(12504): INFO/System.out(12504): INFO/System.out(12504): getProperties().id = 1073834816 getProperties().size() = 37 P2: onStart 0 getProperties().size() = 38

31

Android Processes
Zygote > Upon startup Zygote process is created which partially initializes a VM instance Core system libraries dex-files are loaded (mmap) Dalvik VM is initialized and shared heap (which contains Home objects used by all processes) is created APK > Upon start of an activity the Zygote process is forked Code Application specific dex files are loaded (mmap) Application specific heap (and VM structures) are initialized Maps => Core system libraries are shared! Zygote APK Code System Libraries

32

Service
Characteristics > Execution of long running tasks and business logic outside an activity E.g. a background task that has to download data periodically > Services can explicitly be started and stopped > Communication with service In-process if service runs in same APK Inter-Process Communication across APKs (AIDL)

33

Service
Explicit control > startService(intent) onCreate -> onStart > stopService(intent) onDestroy Implicit control > bindService(intent, conn, flags) onCreate -> onBind > unbindService(conn) onUnbind

34

Service Inter Process Communication


Binder > Bridges Kernel and Process space > Proxy and Stub classes are generated from AIDL definitions AIDL data types > Primitive types, String, CharSequence > List, Map > AIDL generated interfaces > Parcelable classes AIDL extensions > in, out, inout > oneway

on parametres for asynchronous invocations

35

Service Sample: AIDL Interface


interface ICounterService { long getCurrentValue(); void setCounterListener(in ICounterListener l); } interface ICounterListener { void valueChanged(long value); }

IBinder

Binder

ICounterService

ICounterService.Stub CounterBinder

ICounterService.Stub.Proxy

36

Service Sample: Manifest


<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ch.fhnw.imvs.counter" android:versionCode="1" android:versionName="1.0"> <application> <service android:name=".CounterService" > <intent-filter> <action android:name="ch.fhnw.imvs.counter.ICounterService"/> </intent-filter> </service> </application> </manifest>

37

Service Sample: Invocation


Bind Service
Intent start = new Intent("ch.fhnw.imvs.counter.ICounterService"); conn = new ServiceConnection() { public void onServiceConnected(ComponentName name, IBinder b) { ICounterService service = ICounterService.Stub.asInterface(b); service.setCounterListener(new ICounterListener.Stub() { public void valueChanged(final long value) { } }); } }); bindService(start, conn, Context.BIND_AUTO_CREATE);

Unbind Service
unbindService(donn);

38

Content Provider
Content Provider > The only way to share data between Android Packages > Implements a standard set of methods to provide access to data > Any form of storage can be used APK SQLite DB Process Files APK Activity Activity Remote Store
Process
Activity Content Provider

39

Content Provider
Content Provider Interface
abstract class ContentProvider { public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder); public Uri insert(Uri uri, ContentValues values) public int delete(Uri uri, String selection, String[] selectionArgs); String getType(Uri uri); public int update(ContentURI uri, ContentValues values, String selection, String[] selectionArgs) }

40

Content Provider
Access to Data Providers > Comparable to a DB Access (Cursor) > Identification via URI content://contacts/phones
String[] projections = new String[]{ "number", "name", "_id", "photo"}; Cursor cur = managedQuery( new ContentURI("content://contacts/phones"), projections, null, "name ASC");

41

Content Provider Sample


public class Provider extends android.content.ContentProvider { public static final android.net.Uri CONTENT_URI = Uri.parse("content://ch.fhnw.imvs.fibonacci/numbers"); public static final String ID = BaseColumns._ID; public static final String VALUE = "value"; public boolean onCreate() { return true; } public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){ MatrixCursor c =new MatrixCursor(new String[]{ID,VALUE},10); for(int i=0; i<10; i++) c.addRow(new Object[]{i, getNumber(i)}); return c; }

42

Content Provider Sample Client


private void listFibonacciNumbers(){ String[] projection = new String[]{BaseColumns._ID, "value"}; Cursor cur = this.managedQuery( Uri.parse("content://ch.fhnw.imvs.fibonacci/numbers"), projection, null, null, null); cur.moveToFirst(); do { log.append(String.format("fib(%s) = %s", cur.getString(0), cur.getString(1))); log.append("/n"); } while (cur.moveToNext()); }

43

Android Application Model: Summary


Scalability > Model well suited for mobile devices Optimized memory usage Linux-based Security Model Component Model > Interesting programming model > Existing activities may be reused / extended

Dominik Gruntz University of Applied Sciences Steinackerstrasse 5 5210 Windisch / Switzerland

dominik.gruntz@fhnw.ch

También podría gustarte