Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Android Application Model Component Model for Mobile Applications Dominik Gruntz University of Applied Sciences Northwestern Switzerland, Brugg-Windisch 8925 2 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" 3 AGENDA Android Components > Activities – Intents & Filters – Task / Application – Lifecycle – Processes and Threads > Services > Content Providers 4 Android Software Stack > Java > C/C++ > Kernel 5 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 6 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 7 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")); 8 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) 9 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 APK Content Provider 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 > Comparable with EJB's stateful session beans (SFSB) > Each Android component has a managed lifecycle Maps 16 Activity Life Cycle New Active / Running > Activity is in foreground > Activity has focus Paused > Still visible, partially overlaid > Focus lost onRestart() onStart() onResume() onCreate() onStart() [onRestoreInstanceState()] onResume() Running onResume() onStop() Paused Stopped Stopped > Activity is not visible Destroyed > Activity was terminated or killed onSaveInstanceState() onPause() 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 1 Process 1 1 Thread 1 Looper 1 1 Handler * 1 Message Queue 22 Process / Thread ActivityThread > Manages the main thread in an application process > Calls Looper.loop APK Looper.loop while(true){ Message m=queue.next(); // may block if(m!=null){ m.target.dispatchMessage(m); m.recycle(); } } Process Activity Thread Local Service Calls Looper Activity Intent Recvr UI Events Message Queue 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 [email protected]