Professional Documents
Culture Documents
M3 - Mad
M3 - Mad
Intents
• Used to activate a component in an application
• Used as a message-passing mechanism
• If we want to invoke a new activity from our current activity, then we need to fire
an intent specifying the new activity
• If we want to start another application from our activity, then also we require
intent
• Intents have been classified into two types
o Explicit Intents
o Implicit Intents
Uses of Intents
1. Starting an activity:
o startActivity (Intent)
▪ The startActivity(Intent) method is used to start a new activity, which will
be placed at the top of the activity stack
▪ It takes a single argument, an Intent, which describes the activity to be
executed
o startActivityForResult (Intent, int): Used to get a result back from an activity
when it ends
2. Starting a service:
o A Service is a component that performs operations in the background without a
user interface
o With Android 5.0 (API level 21) and later, you can start a service with
JobScheduler
o For versions earlier than Android 5.0 (API level 21), you can start a service by
using methods of the Service class startService(Intent)
3. Delivering a broadcast:
o A broadcast is a message that any app can receive
o The system delivers various broadcasts for system events, such as when the
system boots up or the device starts charging
o You can deliver a broadcast to other apps by using method
sendBroadcast(Intent)
Explicit Intents
• Explicit intent is called for internal communication of an application
• It is being invoked by mentioning the target component name (like an activity)
• The component or activity can be specified which should be active on receiving the
intent
• For this reason, mostly it is used for intra application communication
• Example:
Intent i = new Intent (getApplicationContext(),
MyOtherActivity.class);
startActivity(i);
• After startActivity is called, the new Activity (in this example MyOtherActivity) will
be created and become visible and active, moving to the top of the Activity stack
• Calling finish on the new Activity, or pressing the hardware back button, will close
it and remove it from the stack.
• Alternatively, developers can navigate to the previous Activity, or yet another
Activity, by calling startActivity
• Passing Values via Explicit Intents
Intent i = new Intent(Main_Activity.this, Activity2.class);
i.putExtra("uname", username);
i.putExtra("email", emailid);
startActivity(i);
Retrieving Values in Activity 2 (snippet inside the onCreate() function)
Intent thisActivity = getIntent();
String userName = thisActivity.getStringExtra(“uname”);
String emailID = thisActivity.getStringExtra(“email”);
Implicit Intent
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name=
"android.intent.action.MAIN"/>
<category android:name=
"android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name=
"android.intent.action.SEND"/>
<category android:name=
"android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
<intent-filter>
<action android:name=
"android.intent.action.VIEW"/>
<category android:name=
"android.intent.category.DEFAULT"/>
<category android:name=
"android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
</intent-filter>
</activity>
</application>
</manifest>
Services
• Android service is a component that is used to perform operations on the
background such as playing music, handle network transactions, interacting
content providers etc
• It doesn't have any UI
• Services run in the background — updating your Content Providers, firing Intents,
and triggering Notifications
• They are the perfect means of performing ongoing or regular processing and of
handling events even when your application’s Activities are invisible or inactive,
or have been closed
• Services are started, stopped, and controlled from other application components,
including other Services, Activities, and Broadcast Receivers
Implementing a Service
• To define a Service, create a new class that extends Service
• You’ll need to override onBind and onCreate
• Skeleton of implementation:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
@Override
public void onCreate() {
// TODO: Actions to perform when service is created.
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Replace with service binding implementation.
return null;
}
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Launch a background thread to do processing.
return Service.START_STICKY;
}
}
• Services are launched on the main Application thread
• The standard pattern for implementing a Service is to create and run a new thread
from onStartCommand() to perform the processing in the background and stop
the Service when it’s complete
• This pattern lets onStartCommand() complete quickly, and lets you control the
restart behavior using one of the following Service constants:
o START_STICKY: If you return this value, onStartCommand() will be called
every time your Service restarts after being terminated by the run time.
o START_NOT_STICKY: This mode is used for Services that are started to
process specific actions or commands and need to be restarted after being
terminated by the run time.
• To start a Service explicitly, call startService. Ex:
startService(new Intent(this, myService.class));
• To stop a service. Ex:
stopService(new Intent(this, service.getClass()));
Service Lifecycle
• The lifecycle of service can follow two different paths:
o Started
o Bound
• Started/Unbounded Service :
o A service is started when component (like activity) calls startService() method
o It runs in the background indefinitely
o The service can stop itself by calling the stopSelf() method
• Bound Service :
o A service is bound when another component (e.g. client) calls bindService()
o The client can unbind the service by calling the unbindService() method
o The service cannot be stopped until all clients unbind the service
Service Lifecycle
• onCreate():
o Executed when the service is first created in order to set up the initial
configurations you might need.
o This method is executed only if the service is not already running.
• onStartCommand():
o Executed every time startService() is invoked by another component, like an
Activity or a BroadcastReceiver.
o When you use this method, the Service will run until you call stopSelf() or
stopService()
• onBind():
o Executed when a component calls bindService() and returns an instance of
IBinder, providing a communication channel to the Service.
o A call to bindService() will keep the service running as long as there are
clients bound to it.
If the service is bound, the active lifetime ends when onUnbind() returns.
• onUnbind(): Called when all clients have disconnected from a particular interface
published by the service.
A started service is stopped by a call to either stopSelf() or stopService()
• stopSelf() / stopService(): Stops the service, if it was previously started.
• onDestroy(): Executed when the service is no longer in use and allows for disposal
of resources that have been allocated.
• Apps also send custom broadcasts, for example, to notify other apps of something
that they might be interested in (Ex: some new data has been downloaded)
• Ex: when the system switches in and out of airplane mode. System broadcasts are
sent to all apps that are subscribed to receive the events.
• Steps to make Broadcast Receiver works for the system
o Creating the Broadcast Receiver
o Registering Broadcast Receiver
Broadcast Events
Async Task
• AsyncTask (Asynchronous Task) allows us to run the instruction in the background
and then synchronize again with our main thread.
• AsyncTask must be subclassed to be used. The subclass will override at least one
method doInBackground(Params), and most often will override a second one
onPostExecute(Result).
• AsyncTask class is used to do background operations that will update the UI.
• Used mainly for short operations.
AsyncTask Workflow:
o AsyncTask is executed using onPreExecute().
o Then, onPreExecute() calls doInBackground() for background processes
o Then, doInBackground() calls onPostExecute() method to update the UI.
• onPreExecute():
o It is invoked on the UI thread before the task is executed.
o This step is normally used to setup the task, for instance by showing a
progress bar in the user interface
• doInBackground():
o It is invoked on the background thread immediately after onPreExecute()
finishes executing.
o This step is used to perform background computation that can take a long
time. The parameters of the asynchronous task are passed to this step.
• onProgressUpdate():
o This method is used to display any form of progress in the user interface
while the background computation is still executing.
o Ex: it can be used to animate a progress bar or show logs in a text field.
• onPostExecute():
o It is invoked on the UI thread after the background computation finishes.
o The result of the background computation is passed to this step as a
parameter.
Syntax of AsyncTask
• To use AsyncTask you must subclass it. The parameters are the following
AsyncTask <TypeOfVarArgParams, ProgressValue, ResultValue>
o TypeOfVarArgParams: It is the type of the parameters sent to the task upon
execution.
o ProgressValue: It is the type of the progress units published during the
background computation.
o ResultValue: It is the type of result of the background computation.
• Skeleton example:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
Resolution Independence
• A display’s pixel density is calculated as a function of the physical screen size and
resolution, referring to the number of physical pixels on a display relative to the
physical size of that display.
• It’s typically measured in dots per inch (dpi).
• Using Density-Independent Pixels
o As a result of the variations in screen size and resolution for Android devices,
the same number of pixels can correspond to different physical sizes on
different devices based on the screen’s DPI.
o This makes it impossible to create consistent layouts by specifying pixels.
o Instead, Android uses density-independent pixels (dp) to
▪ specify screen dimensions that
▪ scale to appear the same on screens of the same size
▪ but which use different pixel densities.
o In addition to dp units, Android also uses a scale-independent pixel (sp) for
the special case of font sizes.
• Resource Qualifiers for Pixel Density
o Scaling bitmap images can result in either
▪ lost detail (when scaling downward) or
▪ pixilation (when scaling upward).
o To ensure that your UI is crisp, clear, and devoid of probelms, it’s good
practice to include multiple image assets for different pixel densities.
o For simple types of images (usually icons), you can avoid creating separate
images for each density by using vector graphics.
o Because vector graphics define the illustration with geometric line paths
instead of pixels, they can be drawn at any size without scaling problems.
o When using Drawable resources that cannot be dynamically scaled well,
you should create and include image assets optimized for each pixel density
category:
res/layout/main_activity.xml
# For handsets (smaller than 600dp available width)
res/layout-sw600dp/main_activity.xml
# For 7” tablets (600dp wide and bigger)
o The smallest width qualifier specifies the smallest of the screen's two
sides (height and width), regardless of the device's current orientation, so
it's a simple way to specify the overall screen size available for your layout.
• Use the Available Width qualifier
o Instead of changing the layout based on the smallest width of the screen,
you might want to change your layout based on how much
width or height is currently available.
o Ex: if you have a two-pane layout, you might want to use that, whenever
the screen provides at least 600dp of width, which might change
depending on whether the device is in landscape or portrait orientation.
o In this case, you should use the "available width" qualifier as follows:
res/layout/main_activity.xml
# For handsets (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml
# For 7” tablets or any screen with 600dp available width
o If the available height is a concern for you, then you can do the same using
the "available height" qualifier.
o For example, layout-h600dp for screens with at least 600dp of screen
height.
• Add orientation qualifiers
o Although you may be able to support all size variations using only
combinations of the "smallest width" and "available width" qualifiers, you
might also want to change the user experience when the user switches
between portrait and landscape orientations.
o For that you can add the port or land qualifiers to your resource directory
names. Just be sure these come after the other size qualifiers.
For example:
res/layout/main_activity.xml
# For handsets
res/layout-land/main_activity.xml
# For handsets in landscape
res/layout-sw600dp/main_activity.xml
# For 7” tablets
res/layout-sw600dp-land/main_activity.xml
# For 7” tablets in landscape