02 - Android App
App components
- Logging
- Context
- Activity
- Intent
- Service
- Broadcasts
Logging
Full support in ide
Use android.util.Log
Verbose Log.v()
, debug Log.d()
, info Log.i()
, warn Log.w()
, error Log.e()
, or "what a terrible Failure" Log.wtf()
Deployed application should not contain logging code!
Use BuildConfig.DEBUG flag for checking state (deployed or not)
TAG – string
1 2 3 4 5 6 7 8 9 10 |
|
public static int w (String tag, Throwable tr)
public static int w (String tag, String msg, Throwable tr)
Context
- The Context class is an "Interface to global information about an application environment".
- The Context class itself is declared as abstract class, whose implementation is provided by the Android OS. The documentation further provides that Context "…allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc".
- the Context provides the answer to the components question of "where the hell am I in relation to app/system generally and how do I access/communicate with the rest of the app?"
Activity
- Activity – one screen (UI and code)
- User interface – 1..n activities
- Every activity is separate component
- Activity can start other activities
- Back stack (lifo)
- Activity has to be declared in manifest!
Many predefined activities
- Activity
- FragmentActivity
- ListActivity
- PreferenceActivity
- TabActivity
One activity in app is designated as "Main"
Launched on first app activation
Every time new activity is started, previous one is stopped
Previous activity is stored in the back stack
When activity is stopped/paused, callback methods are called
Callbacks – create, resume, stop, destroy, etc…
Create new activity
- Create subclass of Activity (or subclass of subclass of Activity)
- Implement callbacks
- override fun OnCreate(…)
- Implement user interface
- XML layout file
- Or programmatically
- Declaration in AndroidManifest is mandatory
1 2 3 4 5 6 7 8 9 10
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Demo2022s01"> <activity android:name=".SecondActivty" android:exported="false" />
- Specify intent filters
- Intent filter declares, how other system components may use this activity
- Auto-created stub for main activity
- Action action.MAIN – activity responds to the "main" action
- Category category.LAUNCHER – actitvity is placed into launcher category
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Start new activity
- startActivity(intent)
- Starting your own activity – specify class name
1 2 |
|
- Calling other activities
- Intent.EXTRA_EMAIL – stores list of email recipients
1 2 3 |
|
Start new activity, wait for result
Deprecated, classic way
- StartActivityForResult()
- Implement onActivityResult() callback method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Current way
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Shut down activity
- finish() – activity closes itself
- shut down previously started activity – finishActivity(id)
Activity lifecycle
Three essential states
- Resumed
- In foreground, has user focus. "running"
- Paused
- Activity is partially visible, and is "alive". Can be killed by system in low memory situation
- Stopped
- Activity is 100% obscured by another activity. It is alive, but is not attached to the window manager. Can be killed by system, when memory is needed.
Paused or Stopped – system calls finish() method on activity. When activity is reopened, it must be created again
Lifecycle callbacks
- Fundamental callbacks
- Must always call the superclass implementation before doing any work
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Lifecycle flow
SaveInstanceState
- system calls onSaveInstanceState() before making the activity vulnerable to destruction
- Passes Bundle, as name-value pairs
- Save state, using
- putString() and putInt()
- Bundle is passed back in
- onCreate() and onRestoreInstanceState()
Conf changes
Orientation change, physical keyboard, language
System recreates the running activity
- calls onDestroy(),
- then immediately calls onCreate()
Intent and Intent filters
- Messaging object, used for requesting action from another app component
- Fundamental uses
- Start an activity
- startActivity or startActivityForResult
- Start a service
- startService or bindService
- Deliver broadcast
- sendBroadcast, sendOrderedBroadcast, or sendStickyBroadcast
- Start an activity
Explicit intents
- Specify component by name (usually in your own app)
1 2 3 4 |
|
Implicit intents
- Declare general action to perform
- System searches in manifests (intent-filter) for suitable activity
- If several are found, user is presented with dialog for picking
1 2 3 4 5 6 7 8 9 10 |
|
- Forcing an app chooser
- To show the chooser, create an Intent using
createChooser()
and pass it tostartActivity()
- To show the chooser, create an Intent using
1 2 3 4 5 6 7 8 9 10 11 |
|
Intent filter
- To advertise which implicit intents your app can receive
- declare one or more intent filters for each of your app components with an
<intent-filter>
element in your manifest file - Action
- intent action accepted, in the name attribute
- Data
- type of data accepted, using one or more attributes that specify various aspects of the data URI (scheme, host, port, path, etc.) and MIME type
- Category
- category accepted, in the name attribute.
- In order to receive implicit intents, you must include the CATEGORY_DEFAULT
Activity declaration with an intent filter to receive an ACTION_SEND intent when the data type is text
1 2 3 4 5 6 7 |
|
An implicit intent is tested against a filter by comparing the intent to each of the three elements.
To be delivered to the component, the intent must pass all three tests.
Social app
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Receiving intent on activity launch
Parse and check intent in OnCreate
1 2 3 4 5 6 7 8 9 10 11 |
|
Service
- Runs in the background without direct interaction with the user
- Not bound to the lifecycle of an activity
- Used for repetitive and potentially long running operations
- Internet downloads
- checking for new data
- Streaming
- GPS/Sensors
- Service runs in the same process as the main thread of the app
- Use asynchronous processing in the service
Paltform services
- Predefined system services
- Application can use them, given the right permissions
getSystemService()
1 2 3 4 5 |
|
Custom services
- Declare in manifest
- Inside
<application>
tags!
- Inside
- Extend the Service class or one of its subclasses.
- Start service
- Can also start via
bindService()
. Allows direct communication with the service - Use
android:exported="false"
for keeping service private
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 |
|
- start the service
1 2 3 4 5 |
|
Service restart
- START_STICKY
- Service is restarted if it gets terminated. Intent data passed to the onStartCommand method is null. Used for services which manages their own state and do not depend on the Intent data.
- START_NOT_STICKY Service is not restarted. Used for services which are periodically triggered anyway.
- START_REDELIVER_INTENT
- Similar to Service.START_STICKY but the original Intent is re-delivered to the onStartCommand method.
Service stop
stopService()
One call to the stopService()
method stops the service.
stopSelf()
– service terminates itself. Used when service finishes its work.
Communicating with service
-
Simple scenario – no direct communication.
Service receives intent when starting. -
Activity binds to local service
IBinder
,onBind()
-
Using receiver
Service broadcasts events
Activity registers broadcast receiver and receives events from service
Service lifecycle
Broadcasts
- Two types of messages – Local (inside your App) or Global
- IntentFilter
- Receiver declared in code or in Manifest
IntentFilter – you can only receive declared broadcasts
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Internal broadcast receiver – inside main class (or service)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Register and unregister your receiver
Do not double register!
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Send out local brodcasts (in service for example)
1 2 3 4 |
|
Scheduled tasks
Use scheduledExecutorService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|