0% found this document useful (0 votes)
163 views28 pages

Views: View Is The Basic Building Block of UI (User Interface) in Android. View Refers To

Views are the basic building blocks of the Android user interface. A view occupies an invisible rectangle on screen and can display content like text, images, buttons, etc. Views have properties like size, padding, and gravity that determine how they are displayed. Layouts are view groups that are used to arrange views on screen. The most common layouts are LinearLayout, RelativeLayout, and FrameLayout. Activities use views and layouts to build app screens. Views can respond to user input through event listeners. Menus are also views that provide options to users. Strings, styles, themes, drawables, and other resources are used to customize the appearance and text of views. Dialogs like AlertDialogs can interrupt users with
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
163 views28 pages

Views: View Is The Basic Building Block of UI (User Interface) in Android. View Refers To

Views are the basic building blocks of the Android user interface. A view occupies an invisible rectangle on screen and can display content like text, images, buttons, etc. Views have properties like size, padding, and gravity that determine how they are displayed. Layouts are view groups that are used to arrange views on screen. The most common layouts are LinearLayout, RelativeLayout, and FrameLayout. Activities use views and layouts to build app screens. Views can respond to user input through event listeners. Menus are also views that provide options to users. Strings, styles, themes, drawables, and other resources are used to customize the appearance and text of views. Dialogs like AlertDialogs can interrupt users with
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 28

Views

View is the basic building block of UI(User Interface) in android. View refers to
the android.view.View class, which is the super class for all the GUI
components like TextView, ImageView, Button etc.
View can be considered as a rectangle on the screen that shows some type of
content. It can be an image, a piece of text, a button or anything that an
android application can display. The rectangle here is actually invisible, but
every view occupies a rectangle shape.
The question that might be bothering you would be , what can be the size of
this rectangle?
The answer is either we can set it manually, by specifying the exact size(with
proper units) or by using some predefined values. These predefined values
are match_parent and wrap_content.
match_parent means it will occupy the complete space available on the display
of the device. Whereas, wrap_content means it will occupy only that much
space as required for its content to display.

XML syntax for creating a View


Now, as we have explained earlier as well, to draw anything in your android
application, you will have to sepcify it in the design XML files. And to add
functionality we will create Java files.
There are two attributes that are necessary for every View. These
are: android:layout_height and android:layout_width.
android:padding="10dp" android:layout_margin="10dp"
Gravity & Layout_gravity:

android:gravity sets the gravity of the content of the View its used on.


android:layout_gravity sets the gravity of the View or Layout in its parent.

The Programmatic Approach: In this we define/create our Views in the Java


source file. We will learn about this approach in details later, as of now here is
a sample code to add a Button to our view.

Button myButton = new Button(this);

myButton.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,

LinearLayout.LayoutParams.MATCH_PARENT));

myLayout.addView(myButton);

ViewGroup
We have already learned about the various Views available in Android OS to
create various UI components of your Android App.
But how will you arrange all those view components to appear in an ordered
manner on the device screen. Android Layouts are used to arrange the views
on the device's screen.
ViewGroup is the base class for all the layouts and view containers.
The ViewGroup is the base class for Layouts in android,
like LinearLayout, RelativeLayout, FrameLayout etc.
In other words, ViewGroup is generally used to define the layout in which
views(widgets) will be set/arranged/listed on the android screen.

Most commonly used Android layout types


Linear Layout

A layout that arranges other views either horizontally in a single column or


vertically in a single row.

Set android:orientation to specify whether child views are displayed in a row or


column.
RelativeLayout

RelativeLayout is a view group that displays child views in relative positions. The
position of each view can be specified as relative to sibling elements (such as to
the left-of or below another view) or in positions relative to the
parent RelativeLayout area (such as aligned to the bottom, left or center).

 Web View

 TabularLayout

 ListView

 GridView

Android Input Events (Event Listeners, Event Handling)


To respond to an event of a particular type, the view must register an
appropriate event listener and implement the corresponding callback method.
 
For example, if a button is to respond to a click event it must register
to View.onClickListener event listener and implement the
corresponding onClick() callback method. In application when a button click
event is detected, the Android framework will call the onClick() method of that
particular view.

@Override
protected void onCreate(Bundle savedInstanceState) {
    ….
    // Capture button from our layout
    Button button = (Button)findViewById(R.id.btnShow);
    // Register onClick listener with the below implementation
  TextView tView = (TextView)findViewById(R.id.txtResult);
    button.setOnClickListener(btnListener);
….
}
// Anonymous implementation of OnClickListener
private View.OnClickListener btnListener = new View.OnClickListener() {
    public void onClick(View v) {
        // do something when the button is clicked
 tView.setText("You Clicked On Button");
    }
};

 android:gravity: This can be used to set the position of any View on the app

screen. The available value are right, left, center, center_vertical etc. You


can also use to values together, using the | symbol.
 android:textSize: To set text size inside button.

 android:background: To set the background color of the button.

 Picture can be added to the button, alongside the text by


using android:drawableRight, android:drawableLeft, android:drawableTop 
and android:drawableBottom, respectively.:

Menus
Menus are a common user interface component in many types of applications.
To provide a familiar and consistent user experience, you should use
the Menu APIs to present user actions and other options in your activities.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          android:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help" />
</menu>

What is Strings.xml and Why do we need it?

String.xml is a single location for various strings your application needs. here
every string has a unique id, this id you use in your code to use that string. 
Why do we need it?
Instead of providing the string id we can just provide the actual string.

android:text=” i m a hard core text here” instead


of android:text=”@string/hello_world”
then why do we do this??, you can think of a scenario when you have to write
a same string at more than 10-20 places and if you don’t use the string id and
you want to change the string value, you will have to change it at every place
but if you are using string id, you need to change it at only one place.

Where it is located in your project.?


Your Project-> res -> values -> string.xml

Styles and Themes


Styles and themes on Android allow you to separate the details of your app
design from the UI structure and behavior, similar to stylesheets in web design.

A style is a collection of attributes that specify the appearance for a


single View. A style can specify attributes such as font color, font size,
background color, and much more.

A theme is a type of style that's applied to an entire app, activity, or view


hierarchy—not just an individual view. When you apply your style as a theme,
every view in the app or activity applies each style attribute that it supports.
Themes can also apply styles to non-view elements, such as the status bar and
window background.
Styles and themes are declared in a style resource file in res/values/, usually
named styles.xml.

<?xml version="1.0" encoding="utf-8"?>


<resources>
    <style name="GreenText" parent="TextAppearance.AppCompat">
        <item name="android:textColor">#00FF00</item>
    </style>
</resources>

Android AlertDialog Example

Android AlertDialog can be used to display the dialog message with OK and


Cancel buttons. It can be used to interrupt and ask the user about his/her
choice to continue or discontinue.

Android AlertDialog is composed of three regions: title, content area and


action buttons.

Android AlertDialog is the subclass of Dialog class.

Drawable resources
A drawable resource is a general concept for a graphic that can be drawn to
the screen and which you can retrieve with APIs such as getDrawable(int) or
apply to another XML resource with attributes such
as android:drawable and android:icon.

Toasts overview
A toast provides simple feedback about an operation in a small popup. It only fills the
amount of space required for the message and the current activity remains visible
and interactive. Toasts automatically disappear after a timeout.

For example, clicking Send on an email triggers a "Sending message..." toast, as


shown in the following screen capture:

Toasts are not clickable. If user response to a status message is required, consider
instead using a Notification.

Material Design
Material Design is a visual language that synthesizes the classic principles of
good design with the innovation of technology and science.

Intents and Intent Filters


An Intent is a messaging object you can use to request an action from
another app component. Although intents facilitate communication between
components in several ways, there are three fundamental use cases:

Starting an activity
An Activity represents a single screen in an app. You can start a new instance
of an Activity by passing an Intent to startActivity(). The Intent describes the
activity to start and carries any necessary data.
If you want to receive a result from the activity when it finishes,
call startActivityForResult(). Your activity receives the result as a
separate Intent object in your activity's onActivityResult() callback.

Starting a service
A Service is a component that performs operations in the background without
a user interface. With Android 5.0 (API level 21) and later, you can start a
service with JobScheduler
Delivering a broadcast
A broadcast is a message that any app can receive. The system delivers various
broadcasts for system events, such as when the system boots up or the device
starts charging. You can deliver a broadcast to other apps by passing
an Intent to sendBroadcast() or sendOrderedBroadcast().

Intent types

There are two types of intents:

 Explicit intents specify which application will satisfy the intent, by


supplying either the target app's package name or a fully-qualified component
class name. You'll typically use an explicit intent to start a component in your
own app, because you know the class name of the activity or service you want
to start. For example, you might start a new activity within your app in
response to a user action, or start a service to download a file in the
background.
 Implicit intents do not name a specific component, but instead declare a
general action to perform, which allows a component from another app to
handle it. For example, if you want to show the user a location on a map, you
can use an implicit intent to request that another capable app show a specified
location on a map.
Figure 1. How an implicit intent is delivered through the system to start
another activity: [1] Activity A creates an Intent with an action description and
passes it to startActivity(). [2] The Android System searches all apps for an
intent filter that matches the intent. When a match is found, [3] the system
starts the matching activity (Activity B) by invoking its onCreate() method and
passing it the Intent.

Forcing an app chooser

When there is more than one app that responds to your implicit intent, the
user can select which app to use and make that app the default choice for the
action. The ability to select a default is helpful when performing an action for
which the user probably wants to use the same app every time, such as when
opening a web page (users often prefer just one web browser).

Moving between Activities with Intents


 add a new Activity

 add a Button that when pressed goes to that new Activity, using
an Intent

 send information between the Activities using an Intent Extra

To allow the user to move from the MainActivity to the SecondActivity, we’re
going to add a Button and a method that will be ran when that button is
tapped.
To add the button, go to activity_main.xml and add a Button (below I first add
a vertical LinearLayout and change the default “Hello World” TextView to “First
Screen”:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.whatever.twoscreens.MainActivity">

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="18dp">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="First Screen"
android:textSize="24sp"
android:textAlignment="center" />

<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:onClick="onButtonClick" />
</LinearLayout>
</RelativeLayout>
Right, open the MainActivity java file now and we’ll create the onButtonClick
method:

Here’s the code for onButtonClick:


public void onButtonClick(View v){
Intent myIntent = new Intent(getBaseContext(), SecondActivity.class);
startActivity(myIntent);
}
public void onButtonClick(View v){
is declaring the method. The void means that there’s no value “returned” from
the method.
Intent myIntent = new Intent(getBaseContext(), SecondActivity.class);
Here we create a variable called myIntent which is an instance of
the Intent Class, which we use to move between Activities. The important bit is:
SecondActivity.class
This is where we specify which Activity the Intent goes to. If we had called our
Activity RecipeActivity, then that line would be instead:
Intent myIntent = new Intent(getBaseContext(), RecipeActivity.class);
Then:
startActivity(myIntent);
actually starts a new Activity, using the myIntent Intent variable.
Let’s try it out! Run the app and hit the button, it should go from the first screen
to the second (blank) one.
So now you can add a new Activity and allow the user to go to it, using a Button
which using an Intent.
Sending information between Activities.
Let’s say we want to pass over a value to the second Activity — one way is to
use an Intent Extra. Add this line to your method:
myIntent.putExtra("value1", "Barcelona");
placed like so:

This creates an “extra” piece of data that has two parts — a Key and
a Value. The Key is the identifier / name for the Value. So in our example, the
Key is “value1” and the actual Value is “Barcelona”.
That’s one side of the story — sending a value. We now need to add code to
the SecondActivity java file to receive the value. First, let’s add a TextView to
the Second Activity — we’ll use this to display the information (“Barcelona”)
that we’re sending from the first Activity:

You can see I’ve added a vertical LinearLayout and two TextViews — one to just
say “Second Screen” and one to display our sent information. I give this on
an ID of “textID”:
We use the ID to get a reference to the TextView in the java file. Go to that java
file now — SecondActivity.java — and add this code to the onCreate method:
String savedExtra = getIntent().getStringExtra("value1");
TextView myText = (TextView) findViewById(R.id.textID);
myText.setText(savedExtra);
placed like:

The
String savedExtra = getIntent().getStringExtra("value1");
creates a new String variable called “savedExtra” and we store in it the Value of
the Intent Extra with the Key “value1”. Note that it uses:
getStringExtra
This is because the value we sent is a String i.e. text. If it was a number, we’d
use getIntExtra e.g.
myIntent.putExtra("value2", 200);
to send the number and
int savedExtraNumber = getIntent().getIntExtra("value2",0);
to retrieve it. Note the o at the end is a default value if the number sent is
empty.
Ok, back to our code. This gets a reference to our TextView variable which has
an ID of “textID”:
TextView myText = (TextView) findViewById(R.id.textID);
and
myText.setText(savedExtra);
sets that TextView to show the received information. Run it and you should see:
Android List View
Android ListView is a view which groups several items and display them in
vertical scrollable list. The list items are automatically inserted to the list using
an Adapter that pulls content from a source such as an array or database.
An adapter actually bridges between UI components and the data source that
fill data into UI Component. Adapter holds the data and send the data to
adapter view, the view can takes the data from adapter view and shows the
data on different views like as spinner, list view, grid view etc.
The ListView and GridView are subclasses of AdapterView and they can be
populated by binding them to an Adapter, which retrieves data from an
external source and creates a View that represents each data entry.

ArrayAdapter
You can use this adapter when your data source is an array. By default,
ArrayAdapter creates a view for each array item by calling toString() on each
item and placing the contents in a TextView. Consider you have an array of
strings you want to display in a ListView, initialize a new ArrayAdapter using a
constructor to specify the layout for each string and the string array −
ArrayAdapter adapter = new
ArrayAdapter<String>(this,R.layout.ListView,StringArray);
Here are arguments for this constructor −
 First argument this is the application context. Most of the case, keep
it this.
 Second argument will be layout defined in XML file and
having TextView for each string in the array.
 Final argument is an array of strings which will be populated in the text
view.
Once you have array adapter created, then simply call setAdapter() on
your ListView object as follows −
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
You will define your list view under res/layout directory in an XML file. For our
example we are going to using activity_main.xml file.
package com.example.ListDisplay;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class ListDisplay extends Activity {


// Array of strings...
String[] mobileArray = {"Android","IPhone","WindowsMobile","Blackberry",
"WebOS","Ubuntu","Windows7","Max OS X"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ArrayAdapter adapter = new ArrayAdapter<String>(this,


R.layout.activity_listview, mobileArray);

ListView listView = (ListView) findViewById(R.id.mobile_list);


listView.setAdapter(adapter);
}
}
Following will be the content of res/layout/activity_main.xml file −
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ListActivity" >

<ListView
android:id="@+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>

</LinearLayout>
Following will be the content of res/values/strings.xml to define two new constants −
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ListDisplay</string>
<string name="action_settings">Settings</string>
</resources>
Following will be the content of res/layout/activity_listview.xml file −
<?xml version="1.0" encoding="utf-8"?>
<!-- Single List Item Design -->

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold" >
</TextView>

RecyclerView overview
The RecyclerView widget is a more advanced and flexible version of ListView.

In the RecyclerView model, several different components work together to


display your data. The overall container for your user interface is
a RecyclerView object that you add to your layout. The RecyclerView fills itself
with views provided by a layout manager that you provide. You can use one of
our standard layout managers (such
as LinearLayoutManager or GridLayoutManager), or implement your own.

The views in the list are represented by view holder objects. These objects are
instances of a class you define by extending RecyclerView.ViewHolder. Each
view holder is in charge of displaying a single item with a view. For example, if
your list shows music collection, each view holder might represent a single
album. The RecyclerView creates only as many view holders as are needed to
display the on-screen portion of the dynamic content, plus a few extra. As the
user scrolls through the list, the RecyclerView takes the off-screen views and
rebinds them to the data which is scrolling onto the screen.

The view holder objects are managed by an adapter, which you create by
extending RecyclerView.Adapter. The adapter creates view holders as needed.
The adapter also binds the view holders to their data. It does this by assigning
the view holder to a position, and calling the
adapter's onBindViewHolder() method. That method uses the view holder's
position to determine what the contents should be, based on its list position.

This RecyclerView model does a lot of optimization work so you don't have to:

 When the list is first populated, it creates and binds some view holders
on either side of the list. For example, if the view is displaying list positions 0
through 9, the RecyclerView creates and binds those view holders, and might
also create and bind the view holder for position 10. That way, if the user
scrolls the list, the next element is ready to display.
 As the user scrolls the list, the RecyclerView creates new view holders as
necessary. It also saves the view holders which have scrolled off-screen, so
they can be reused. If the user switches the direction they were scrolling, the
view holders which were scrolled off the screen can be brought right back. On
the other hand, if the user keeps scrolling in the same direction, the view
holders which have been off-screen the longest can be re-bound to new data.
The view holder does not need to be created or have its view inflated; instead,
the app just updates the view's contents to match the new item it was bound
to.
 When the displayed items change, you can notify the adapter by calling
an appropriate RecyclerView.Adapter.notify…() method. The adapter's built-in
code then rebinds just the affected items.

RecyclerView.Adapter
public static abstract class RecyclerView.Adapter
extends Object

Base class for an Adapter

Adapters provide a binding from an app-specific data set to views that are
displayed within a RecyclerView.
CardView
A FrameLayout with a rounded corner background and shadow.

CardView uses elevation property on Lollipop for shadows and falls back to a


custom emulated shadow implementation on older platforms.

Due to expensive nature of rounded corner clipping, on platforms before


Lollipop, CardView does not clip its children that intersect with rounded
corners. Instead, it adds padding to avoid such intersection
(See setPreventCornerOverlap(boolean) to change this behavior).

Thread
public class Thread
extends Object implements Runnable
java.lang.Object
   ↳ java.lang.Thread
Known direct subclasses
ForkJoinWorkerThread, HandlerThread

A thread is a thread of execution in a program. The Java Virtual Machine allows


an application to have multiple threads of execution running concurrently.

Every thread has a priority. Threads with higher priority are executed in
preference to threads with lower priority. Each thread may or may not also be
marked as a daemon. When code running in some thread creates a
new Thread object, the new thread has its priority initially set equal to the
priority of the creating thread, and is a daemon thread if and only if the
creating thread is a daemon.

When a Java Virtual Machine starts up, there is usually a single non-daemon
thread (which typically calls the method named main of some designated
class). The Java Virtual Machine continues to execute threads until either of
the following occurs:

 The exit method of class Runtime has been called and the security


manager has permitted the exit operation to take place.
 All threads that are not daemon threads have died, either by returning
from the call to the run method or by throwing an exception that propagates
beyond the run method.

There are two ways to create a new thread of execution. One is to declare a
class to be a subclass of Thread. This subclass should override the run method
of class Thread. An instance of the subclass can then be allocated and started.
For example, a thread that computes primes larger than a stated value could
be written as follows:

class PrimeThread extends Thread {


long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}

public void run() {


// compute primes larger than minPrime
 . . .
}
}

The following code would then create a thread and start it running:

PrimeThread p = new PrimeThread(143);


p.start();

The other way to create a thread is to declare a class that implements


the Runnable interface. That class then implements the run method. An
instance of the class can then be allocated, passed as an argument when
creating Thread, and started. The same example in this other style looks like
the following:

class PrimeRun implements Runnable {


long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}

public void run() {


// compute primes larger than minPrime
 . . .
}
}

The following code would then create a thread and start it running:

PrimeRun p = new PrimeRun(143);


new Thread(p).start();

Every thread has a name for identification purposes. More than one thread
may have the same name. If a name is not specified when a thread is created,
a new name is generated for it.

Unless otherwise noted, passing a null argument to a constructor or method in


this class will cause a NullPointerException to be thrown.

AsyncTask
AsyncTask was intended to enable proper and easy use of the UI thread.
However, the most common use case was for integrating into UI, and that
would cause Context leaks, missed callbacks, or crashes on configuration
changes. It also has inconsistent behavior on different versions of the platform,
swallows exceptions from doInBackground, and does not provide much utility
over using Executors directly.

AsyncTask is designed to be a helper class around Thread and Handler and


does not constitute a generic threading framework. AsyncTasks should ideally
be used for short operations (a few seconds at the most.) If you need to keep
threads running for long periods of time, it is highly recommended you use the
various APIs provided by the java.util.concurrent package such
as Executor, ThreadPoolExecutor and FutureTask.
An asynchronous task is defined by a computation that runs on a background
thread and whose result is published on the UI thread. An asynchronous task is
defined by 3 generic types, called Params, Progress and Result, and 4 steps,
called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.

Usage
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).)

Here is an example of subclassing:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {


     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {


         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {


         showDialog("Downloaded " + result + " bytes");
     }
 }
 

Once created, a task is executed very simply:

 new DownloadFilesTask().execute(url1, url2, url3);


 
AsyncTask's generic types
The three types used by an asynchronous task are the following:

1. Params, the type of the parameters sent to the task upon execution.
2. Progress, the type of the progress units published during the background
computation.
3. Result, the type of the result of the background computation.

Not all types are always used by an asynchronous task. To mark a type as
unused, simply use the type Void:

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:

1. onPreExecute(), invoked on the UI thread before the task is executed.


This step is normally used to setup the task, for instance by showing a progress
bar in the user interface.
2. doInBackground(Params...), invoked on the background thread
immediately after onPreExecute() finishes executing. 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. The result of the computation
must be returned by this step and will be passed back to the last step. This step
can also use publishProgress(Progress...) to publish one or more units of
progress. These values are published on the UI thread, in
the onProgressUpdate(Progress...) step.
3. onProgressUpdate(Progress...), invoked on the UI thread after a call
to publishProgress(Progress...). The timing of the execution is undefined. This
method is used to display any form of progress in the user interface while the
background computation is still executing. For instance, it can be used to
animate a progress bar or show logs in a text field.
4. onPostExecute(Result), invoked on the UI thread after the background computation finishes.
The result of the background computation is passed to this step as a parameter.
Cancelling a task
A task can be cancelled at any time by invoking cancel(boolean). Invoking this
method will cause subsequent calls to isCancelled() to return true. After
invoking this method, onCancelled(java.lang.Object), instead
of onPostExecute(java.lang.Object) will be invoked
after doInBackground(java.lang.Object[]) returns. To ensure that a task is
cancelled as quickly as possible, you should always check the return value
of isCancelled() periodically from doInBackground(java.lang.Object[]), if
possible (inside a loop for instance.)

Threading rules
There are a few threading rules that must be followed for this class to work
properly:

 The AsyncTask class must be loaded on the UI thread. This is done


automatically as of Build.VERSION_CODES.JELLY_BEAN.
 The task instance must be created on the UI thread.
 execute(Params...) must be invoked on the UI thread.
 Do not
call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onPro
gressUpdate(Progress...) manually.
 The task can be executed only once (an exception will be thrown if a
second execution is attempted.)

Memory observability
AsyncTask guarantees that all callback calls are synchronized to ensure the
following without explicit synchronizations.

 The memory effects of onPreExecute(), and anything else executed


before the call to execute(Params...), including the construction of the
AsyncTask object, are visible to doInBackground(Params...).
 The memory effects of doInBackground(Params...) are visible
to onPostExecute(Result).
 Any memory effects of doInBackground(Params...) preceding a call
to publishProgress(Progress...) are visible to the
corresponding onProgressUpdate(Progress...) call.
(But doInBackground(Params...) continues to run, and care needs to be taken
that later updates in doInBackground(Params...) do not interfere with an in-
progress onProgressUpdate(Progress...) call.)
 Any memory effects preceding a call to cancel(boolean) are visible after
a call to isCancelled() that returns true as a result, or during and after a
resulting call to onCancelled().

Order of execution
When first introduced, AsyncTasks were executed serially on a single
background thread. Starting with Build.VERSION_CODES.DONUT, this was
changed to a pool of threads allowing multiple tasks to operate in parallel.
Starting with Build.VERSION_CODES.HONEYCOMB, tasks are executed on a
single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can


invoke executeOnExecutor(java.util.concurrent.Executor,
java.lang.Object[]) with THREAD_POOL_EXECUTOR.

Request App Permissions


Every Android app runs in a limited-access sandbox. If an app needs to use
resources or information outside of its own sandbox, the app has to request
the appropriate permission. You declare that your app needs a permission by
listing the permission in the app manifest and then requesting that the user
approve each permission at runtime (on Android 6.0 and higher).

Add permissions to the manifest

On all versions of Android, to declare that your app needs a permission, put
a <uses-permission> element in your app manifest, as a child of the top-
level <manifest> element. For example, an app that needs to access the
internet would have this line in the manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.snazzyapp">

    <uses-permission android:name="android.permission.INTERNET"/>
    <!-- other permissions go here -->

    <application ...>
        ...
    </application>
</manifest>

The system's behavior after you declare a permission depends on how


sensitive the permission is. Some permissions are considered "normal" so the
system immediately grants them upon installation. Other permissions are
considered "dangerous" so the user must explicitly grant your app access. For
more information about the different kinds of permissions, see Protection
levels.

Check for permissions

If your app needs a dangerous permission, you must check whether you have
that permission every time you perform an operation that requires that
permission. Beginning with Android 6.0 (API level 23), users can revoke
permissions from any app at any time, even if the app targets a lower API level.
So even if the app used the camera yesterday, it can't assume it still has that
permission today.

To check if you have a permission, call


the ContextCompat.checkSelfPermission() method. For example, this snippet
shows how to check if the activity has permission to write to the calendar:

KOTLIN
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR)
        != PackageManager.PERMISSION_GRANTED) {
    // Permission is not granted
}

If the app has the permission, the method returns PERMISSION_GRANTED, and


the app can proceed with the operation. If the app does not have the
permission, the method returns PERMISSION_DENIED, and the app has to
explicitly ask the user for permission.

Request permissions
When your app receives PERMISSION_DENIED from checkSelfPermission(), you
need to prompt the user for that permission. Android provides several
methods you can use to request a permission, such as requestPermissions(), as
shown in the code snippet below. Calling these methods brings up a standard
Android dialog, which you cannot customize.

How this is displayed to the user depends on the device Android version as
well as the target version of your application, as described in the Permissions
Overview.

Explain why the app needs permissions

In some circumstances, you want to help the user understand why your app
needs a permission. For example, if a user launches a photography app, the
user probably won't be surprised that the app asks for permission to use the
camera, but the user might not understand why the app wants access to the
user's location or contacts. Before your app requests a permission, you should
consider providing an explanation to the user. Keep in mind that you don't
want to overwhelm the user with explanations; if you provide too many
explanations, the user might find the app frustrating and remove it.

One approach you might use is to provide an explanation only if the user has
already denied that permission request. Android provides a utility
method, shouldShowRequestPermissionRationale(), that returns true if the
user has previously denied the request, and returns false if a user has denied a
permission and selected the Don't ask again option in the permission request
dialog, or if a device policy prohibits the permission.

If a user keeps trying to use functionality that requires a permission, but keeps
denying the permission request, that probably means the user doesn't
understand why the app needs the permission to provide that functionality. In
a situation like that, it's probably a good idea to show an explanation.

More advice about how to create a good user experience when asking for
permission is provided in App Permissions Best Practices.

Request to become the default handler if necessary


Some apps depend on access to sensitive user information related to call logs
and SMS messages. If you want to request the permissions specific to call logs
and SMS messages and publish your app to the Play Store, you must prompt
the user to set your app as the default handler for a core system function
before requesting these runtime permissions.

You might also like