BUSINESS LAYER
Overview• How Android provide supports to implement the ‘business
logic’ of an app?
• In a classic term this means to run code ‘working’ on input data and producing an output
Overview of possible solutions• General solution: worker threads (as provided by java):• Thread, Runnable• T2T communication: Looper,Handler,MessageQueue,Message
• Pre-cooked ‘frameworks’ (based on threads)• mainly: AsyncTask
• Software (OS managed) components • Service • Broadcast receiver
Overview of possible solutions• Interaction with remote resources (eg, via REST) and db
access is a common part of a business logic
• HTTP interaction• Volley, OkHTTP, Picasso,..
• Access to DB• Room
Example of CPU intensive apps• Image related apps
• Video games
• VR/AR
• Image Recognition / Tracking, … • ML support, notably tensorflow light)
• Demo
Threads• Java thread supports:• Thread class• Runnable Interface
• Specific android thread capabilities• How two threads can asynchronously communicate?• How a worker thread can notify the UI thread?
Example of thread usage
No feedback(notification) to the user is required
Thread-to-thread communication• A thread has a queue of messages
(MessageQueue) associated to it.
• A Looper object is used to run a loop for receiving messages
• The queue can store messages with code to be executed (Runnable)
• A Handler allows to send and process Message and Runnableobjects to the queue
Scheduling messages and runnables• Example of scheduling a runnable :• post(Runnable), • postAtTime(Runnable, long), • postDelayed(Runnable, long)• postAtFrontQueue(Runnable)
• Sending a message is accomplisplished with methods:• sendEmptyMessage(int), • sendMessage(Message), • sendMessageAtTime(Message, long)• sendMessageDelayed(Message, long)
• a Message object can contain a bundle of data
Scheduling runnable on activity and views• An Activity has a MessageQueue• It exposes a method to run code on the main UI• Activity.runOnUIThread(Runnable) method
• Similarly, each view also exposes two methods to schedule runnables• View.post(Runnable)• View.postDelayed (Runnable,Long)
Schedule actions on the Main Thread
runOnUIThread
Activity
View
=Runnable
post
postDelayed
Example (this code is wrong. Why)
• As GUI cannot be touched by threads other than the main one
Correct implementationRecall: the .post() method is implemented by View..
it adds a runnable object to the ‘incoming queue’ of the view
AsynTask• AsyncTask is an abstract class that simplifies the
interaction with UI
• This class allows to perform background operations and publishes the results on the UI thread, without having to manipulate threads and/or handlers.
• An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread.
AsyncTask (main methods)
Main Thread (UI Thread)
Worker ThreaddoInBackground()
onPostExecute()
AsyncTask (detailed methods)
Main Thread (UI Thread)
Worker ThreaddoInBackground()
onPostExecute()
publishProgress()
onProgressUpdate()onPreExecute()
Network communication• Volley (Async HTTP )• OKHttp ( third part library supports HTTP/2, very fast,…)• Picasso (image dowloading)
• Deal with REST• Retrovit
Example (okhttp3)client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {call.cancel();
}
@Overridepublic void onResponse(Call call, Response response) throws IOException {
final String myResponse = response.body().string();MainActivity.this.runOnUiThread(new Runnable() {
@Overridepublic void run() {
try {
JSONObject json = new JSONObject(myResponse);String reply = json.getJSONObject("data").getString("first_name");
txtString.setText(+ " "+reply);
} catch (JSONException e) {e.printStackTrace();
}
}});
}
});
Exampleclient.newCall(request).enqueue(new Callback() {
@Overridepublic void onFailure(Call call, IOException e) {
call.cancel();}@Overridepublic void onResponse(Call call, Response response) throws IOException {
final String myResponse = response.body().string();MainActivity.this.runOnUiThread(new Runnable() {
@Overridepublic void run() {
try {JSONObject json = new JSONObject(myResponse);
String reply = json.getJSONObject("data").getString("first_name");txtString.setText(+ " "+reply);
} catch (JSONException e) {e.printStackTrace();
}}
});}
});
Example
jetpack support to remote data source usage
Services• A Service is an application component that runs in
background, not interacting with the user, for an indefinite period of time.
• Services run in the main thread of their hosting process.
• CPU intensive operations (such as MP3 playback) or blocking (such as networking) operations, should spawn its own thread in which to do that work.
Service vs Thread • A service is a software component with its own lifecycle
• A service can run in ‘background’ (not noticed by UI user), or ‘foreground’
• If a service is destroyed by the OS (only under very heavy circumstances) it is re-created according to the restart options
• A service may be private or system-wide • for example be started automatically after the device boot ends
• Android provides a set of system wide services• getSystemService()
Some example of system service• AccessibilityManager, for being notified of key system events (e.g., activities starting) that might be relayed to users via haptic
feedback, audio prompts, or other non-visual cues• AccountManager, for working with Android’s system of user accounts and synchronization• ActivityManager, for getting more information about what processes and components are presently running on the device• AlarmManager, for scheduled tasks (a.k.a., “cron jobs”), covered elsewhere in this book• AppOpsManager, for “tracking application operations on the device”• AppWidgetManager, for creating or hosting app widgets• AudioManager, for managing audio stream volumes, audio ducking, and other system-wide audio affordances• BatteryManager, for finding out about the state of the battery• BluetoothManager, for exposing or connecting to Bluetooth services• ClipboardManager, for working with the device clipboard, covered elsewhere in this book• ConnectivityManager, for a high-level look as to what sort of network the device is connected to for data (e.g., WiFi, 3G)• ConsumerIrManager, for creating “IR blaster” or other IR-sending apps, on hardware that has an IR transmitter• DevicePolicyManager, for accessing device administration capabilities, such as wiping the device• DisplayManager, for working with external displays, covered elsewhere in this book• DownloadManager, for downloading large files on behalf of the user, covered in elsewhere in the book• DropBoxManager, for maintaining your own ring buffers of logging information akin to LogCat• FingerprintManager, for working with fingerprint readers on Android 6.0+ devices• InputMethodManager, for working with input method editors• InputManager, for identifying external sources of input, such as keyboards and trackpads• JobScheduler, for scheduling periodic background work, • KeyguardManager, for locking and unlocking the keyguard, where possible• LauncherApps, for identifying launchable apps on the device (e.g., for home screen launchers), taking into account device
policies• LayoutInflater, for inflating layout XML files into Views, as you saw earlier in the book• LocationManager, for determining the device’s location (e.g., GPS), • MediaProjectionManager, for capturing screenshots and screencasts• MediaRouter, for working with external speakers and displays• MediaSessionManager, for teaching Android about media that you are playing back
Some example of system service• MidiManager, for playing MIDI audio• NetworkStatsManager, “for querying network usage stats”• NfcManager, for reading NFC tags or pushing NFC content• NotificationManager, for putting icons in the status bar and otherwise alerting users to things that have occurred
asynchronously, covered in the chapter on Notification• NsdManager, for network service discovery operations• PowerManager, for obtaining WakeLock objects and such, covered elsewhere in this book• PrintManager, for printing from Android• RestrictionsManager, for identifying and working with restricted operations• SearchManager, for interacting with the global search system• SensorManager, for accessing data about sensors, such as the accelerometer, covered elsewhere in this book• StorageManager, for working with expanded payloads (OBBs) delivered as part of your app’s installation from the Play Store• SubscriptionManager, for dealing with data roaming and other telephony subscription rules• TelecomManager, for dealing with incoming and outgoing phone calls• TelephonyManager, for finding out about the state of the phone and related data (e.g., SIM card details)• TextServicesManager, for working with spelling checkers and other “text services”• TvInputManager, for Android-powered televisions, to find out about TV inputs• UiModeManager, for dealing with different “UI modes”, such as being docked in a car or desk dock• UsageStatsManager, “for querying device usage stats”• UsbManager, for working directly with accessories and hosts over USB• UserManager, for working with multiple user accounts on a compatible device (Android 4.2+ tablets, Android 5.0+ phones)• Vibrator, for shaking the phone (e.g., haptic feedback)• WallpaperService, for working with the device wallpaper• WifiManager, for getting more details about the active or available WiFi networks• WifiP2pManager, for setting up and communicating over WiFi peer-to-peer (P2P) networks• WindowManager, mostly for accessing details about the default display for the device
Service type: Background services• A background service performs an operation that isn't
directly noticed by the user.
• For example, if an app used a service to compact its storage, that would usually be a background service.
• Stating from Oreo, for performance reasons the system imposes restrictions on running background
• The Scheduled Job is recommended for performing background operations
Service type: Foreground services• A foreground service performs some operation that is
noticeable to the user.
• For example, an audio app would use a foreground service to play an audio track. Foreground services mustdisplay a status bar icon. • startForeground(id,Notification) method
• However, if the user wants to listen the music only when interacting with the app, a thread is to be used • Create a thread in onCreate(), start running it in onStart(), and stop
it in onStop(). [source: developer site]
Notication (demo)
Service type: Bounded Services• A bound service is the server in a client-server interface
C S
Service type: Bounded Services• A bound service runs only as long as another application
component is bound to it.
• Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.
Service lifecycle
Example of code
Example• Let’s suppose we want run music in background, i.e., user do
not interact with the application
• We can use the MediaPlayer class to play, for example, an .mp3 file stored in the raw directory• The MediaPlayer has the create(context,id) method that creates an
istance of the MediaPlayer (say player) for the specified resource id
• A simple application will have two buttons (start and stop)
• The start button will call the start method on the player…
• The stop button will call the stop method on the player…
Example
Service PlayerUI Activity(startService)
Main Thread
Process
intent
Example
Service Player
Main Thread
Process
Example
Service PlayerUI Activity(stopService)
Main Thread
Process
intent
Example
startService(intent)
stopService(intent)
Activity is killed
onDestroy()
onStartCommand(…)
X
Activity is created startService(intent) onStartCommand(…)A simple flag avoids to call another instance of MediaPlayer
Bound services• Allows a client to set up a connection (bind) with the
service so that methods can be called• Started with
context.bindService(intent,ServiceConnetcion,Flags)• onBind() returns an interface with methods that can be
called
Example
Service’s public methods are available to the client
Example
mSevice. getRandomNumber()
Bound Service (local/remote service)• A service can be bounded to another SW component, meaning that it
can invoke methods implemented by the service through a proxy (Binder) of the Service (which is seen as a remote object)
• It is possible to access a service running in a different process
Remote services• It is possible to access a service running in a different
process
processA process B
skelethonproxy
IDL
aidl
generates
tool
JobScheduler• Used when a task do not require an exact time, but it could be
scheduled based on a combination of system and user requirements.
• For example, a news app might like to update the news in the morning, but could wait until the device is charging and connected to wifi to update the news, to preserve the user's data and system resources.
• The JobScheduler class allows for setting the conditions, or parameters of running the task.
• The JobScheduler calculates the best time to schedule the execution of the job.
Service activation via bcast receiver• Sometimes a service may need to be started when some
condition is met• Connect to a server only when the wi-fi connection is available (not
GSM)
• These cases may be managed using Broadcast receives
• It may also useful to use a specialized service (Intent Service)
Broadcast Receiver• It’s a software component that reacts to system-wide
events (in the form bcast action)• A receiver has to register to specific intents
Broadcast intents
System-wide intentsThe action specifies that an event is occurred
Intent service• The IntentService class is a convenience class
(subclassed from the Service class) that sets up a worker thread for handling background
• Once the service has handled all queued requests, it simply exits.
• All that is required when using the IntentService class is to implement onHandleIntent(intent) method
Services and broadcast receivers• Suppose we want to check a remote server only when an
internet connection becomes available. • This is one possible solution:• Register a broadcast receiver to the following bcast intent:• ConnectionManager.CONNECTIVITY_ACTION• (When the connectivity changes this intent is fired)
• Check (from the receiver) if the connection is now up• If this is the case, then start an IntentService• The IntentService will use a Socket to open a stream with
the server
Solution
BroadcastReceiver
IntentService
Start
ConnectivityManager.CONNECTIVITY_ACTION
Socket
Send a notification
Registering Broadcast receivers• Registration to receive bcast intent can be done
• Statically (through XML, e.g., <receiver> tag)
• Dynamically (from an activity). Called in the UI thread..
• Statically registered receivers reamin dormant and respond to the intent
• Dynamically registered event are alive as long as the registering activity is alive
• Subscription to some events can only be done dynamically(e.g., TIME_TICK – this is to avoid battery drain)
BroadcastReceiver (demo)• Register to the TIME_TICK event• Warning: the registration can only be done dynamically
from the code. Also, for security reason it cannot be generated (sendBroadcast(…))
when the time changes a toast is displayedUseful for example to perform polling…
Another example (do something periodically)• Check a condition every minute
BroadcastReceiver
Intent Service
Start
Time tick
NotificationManager
Activity A
registerreceiver
Activity B
Create aPendingIntent
Another example (do something periodically)•
AlarmManager
Intent Service
PendingIntent
NotificationManager
Activity
Set a periodic alarm
Activity