Practical part of the "Head First Android Development" book.
Key points:
- Versions of Android have a version number, API level, and code name.
- Android Studio is a special version of IntelliJ IDEA that interfaces with the Android Software Development Kit (SDK) and the Gradle build system.
- A typical Android app is composed of activities, layouts, and resource files.
- Layouts describe what your app looks like. They’re held in the
app/src/main/res/layout
folder. - Activities describe what your app does, and how it interacts with the user. The activities you write are held in the
app/src/main/java
folder. AndroidManifest.xml
contains information about the app itself. It lives in theapp/src/main
folder.- An AVD is an Android Virtual Device. It runs in the Android emulator and mimics a physical Android device.
- An APK is an Android application package. It’s like a JAR file for Android apps, and contains your app’s bytecode, libraries, and resources. You install an app on a device by installing the APK.
- Android apps run in separate processes using the Android runtime (ART).
- The
<TextView>
element is used for displaying text.
Key points:
- The
<Button>
element is used to add a button. - The
<Spinner>
element is used to add a spinner, which is a drop-down list of values. - All GUI components are types of view. They inherit from the Android View class.
strings.xml
is a String resource file. It’s used to separate out text values from the layouts and activities, and supports localization.- Add a String to
strings.xml
using:
<string name="name">Value</string>
- Reference a String in the layout using:
"@string/name"
- Add an array of String values to
strings.xml
using:
<string-array name="array">
<item>string1</item>
...
</string-array>
- Reference a
string-array
in the layout using:"@array/array_name"
- Make a button call a method when clicked by adding the following to the layout:
android:onClick="clickMethod"
- There needs to be a corresponding method in the activity:
public void clickMethod(View view) {
// ...
}
R.java
is generated for you. It enables you to get references for layouts, GUI components, Strings, and other resources in your Java code.- Use
findViewById()
to get a reference to a view. - Use
setText()
to set the text in a view. - Use
getSelectedItem()
to get the selected item in a spinner. - Add a custom class to an Android project by going to
File menu → New ... → Java Class
.
Key points:
- A
task
is two or more activities chained together. - The
<EditText>
element defines an editable text field for entering text. It inherits from the AndroidView
class. - You can add a new activity in Android Studio by choosing
File → New... → Activity
. - Each activity you create must have an entry in
AndroidManifest.xml
. - An intent is a type of message that Android components use to communicate with one another.
- An explicit intent specifies the component the intent is targeted at. You create an explicit intent using:
Intent intent = new Intent(this, Target.class);
- To start an activity, call
startActivity(intent)
. If no activities are found, it throws anActivityNotFoundException
. - Use the
putExtra()
method to add extra information to an intent. - Use the
getIntent()
method to retrieve the intent that started the activity. - Use the
get*Extra()
methods to retrieve extra information associated with the intent.getStringExtra()
retrieves a String,getIntExtra()
retrieves an int, and so on. - An activity action describes a standard operational action an activity can perform. For example, to send a message, use
Intent.ACTION_SEND
. - To create an implicit intent that specifies an action, use:
Intent intent = new Intent(action);
- To describe the type of data in an intent, use the
setType()
method. - Android resolves intents based on the named component, action, type of data, and categories specified in the intent. It compares the contents of the intent with the intent filters in each app’s
AndroidManifest.xml
. An activity must have a category ofDEFAULT
if it is to receive an implicit intent. - The
createChooser()
method allows you to override the default Android activity chooser dialog. It lets you specify a title for the dialog, and doesn’t give the user the option of setting a default activity. If no activities can receive the intent it is passed, it displays a message. ThecreateChooser()
method returns an Intent. - You retrieve the value of a String resource using
getString(R.string.stringname);
Key points:
Each app
runsin its own process
by default.- Only the
main thread
can update the user interface. - Use a
Handler
to schedule code or post code to a different thread. - A
device configuration change
results in the activity being destroyed and recreated. - Your activity inherits the lifecycle methods from the
android.app.Activity
class. If you override any of these methods, you need to call up to the method in the superclass. onSaveInstanceState(Bundle)
enables your activity to save its state before the activity gets destroyed. You can use theBundle
to restore state inonCreate()
.- You add values to a
Bundle
usingbundle.put*("name", value)
. You retrieve values from the bundle usingbundle.get*("name")
. onCreate()
andonDestroy()
deal with the birth and death of the activity.onRestart()
,onStart()
, andonStop()
deal with the visibility of the activity.onResume()
andonPause()
handle when the activity gains and loses the focus.
Key points:
- GUI components are all types of view. They are all subclasses of the
android.view.View
class. - All layouts are subclasses of the
android.view.ViewGroup
class. A view group is a type of view that can contain multiple views. - The layout XML file gets converted to a
ViewGroup
containing a hierarchical tree of views. - A linear layout lists views either horizontally or vertically. You specify the direction using the
android:orientation
attribute. - A frame layout stacks views.
- Use
android:padding*
attributes to specify how much padding you want around a view. - In a linear layout, use
android:layout_weight
if you want a view to use up extra space in the layout. android:layout_gravity
lets you say where you want views to appear in their available space.android:gravity
lets you say where you want the contents to appear inside a view.<ToggleButton>
defines a toggle button that allows you to choose between two states by clicking a button.<Switch>
defines a switch control that behaves in the same way as a toggle button. It requires API level 14 or above.<CheckBox>
defines a checkbox.- To define a group of radio buttons, first use
<RadioGroup>
to define the radio group. Then put individual radio buttons in the radio group using<RadioButton>
. - Use
<ImageView>
to display an image. <ImageButton>
defines a button with no text, just an image.- Add scrollbars using
<ScrollView>
or<HorizontalScrollView>
. - A
Toast
is a pop-up message.
Key points:
Constraint layouts
are designed to work with Android Studio’s design editor. They have their own library and can be used in apps where the minimum SDK is API level 9 or above.- Position views by adding
constraints
. Each view needs at least one horizontal and one vertical constraint. - Center views by adding constraints to opposite sides of the view. Change the view’s bias to update its position between the constraints.
- You can change a view’s size to match its constraints if the view has constraints on opposing sides.
- You can specify a
width:height
aspect ratio for the view’s size. - Clicking on the
Infer Constraints
button adds constraints to views based on their position in theblueprint
.
Key points:
- Sort your ideas for activities into top-level activities, category activities, and create / detail / edit / delete (
CRUD
) activities. Use the category activities to navigate from the top-level activities to the createCRUD
activities. - A list view displays items in a list. Add it to your layout using the
<ListView>
element. - Use
android:entries
in your layout to populate the items in your list views from an array defined instrings.xml
. - An adapter acts as a bridge between an
AdapterView
and a data source.ListViews
andSpinners
are both types ofAdapterView
. - An
ArrayAdapter
is an adapter that works with arrays. - Handle click events on
Buttons
usingandroid:onClick
in the layout code. Handle click events elsewhere by creating alistener
and implementing its click event.
Key points:
- You add a basic app bar by applying a
theme
that contains one. - The
A
ndroid Support Libraries` provide backward compatibility with older versions of Android. - The
AppCompatActivity
class is a type of activity that resides in thev7 AppCompat Support Library
. In general, your activity needs to extend theAppCompatActivity
class whenever you want an app bar that provides backward compatibility with older versions of Android. - The
android:theme
attribute inAndroidManifest.xml
specifies which theme to apply. - You define styles in a style resource file using the
<style>
element. Thename
attribute gives the style a name. The parent attribute specifies where the style should inherit its properties from. - The latest app bar features are in the
Toolbar
class in thev7 AppCompat Support Library
. You can use a toolbar as your app bar. - Add
actions
to your app bar by adding them to amenu resource file
. - Add the items in the menu resource file to the app bar by implementing the activity’s
onCreateOptionsMenu()
method. - You determine what items should do when clicked by implementing the activity’s
onOptionsItemSelected()
method. - Add an
Up button
to your app bar to navigate up the app’s hierarchy. Specify the hierarchy inAndroidManifest.xml
. Use the ActionBarsetDisplayHomeAsUpEnabled()
method to enable theUp button
. - You can share content by adding the
share action provider
to your app bar. Add it by including it in your menu resource file. Call itssetShareIntent()
method to pass it an intent describing the content you wish to share.
Key points:
- A fragment is used to control part of a screen. It
can be reused
across multiple activities. - A fragment has an
associated layout
. - The
onCreateView()
method gets called each time Android needs the fragment’s layout. - Add a fragment to an activity’s layout using the
<fragment>
element and adding aname
attribute. - The fragment lifecycle methods tie in with the states of the activity that contains the fragment.
- The
Fragment
class doesn’t extend theActivity
class or implement theContext
class. - Fragments don’t have a
findViewById()
method. Instead, use thegetView()
method to get a reference to the root view, then call the view’sfindViewById()
method. - A
list fragment
is a fragment that comes complete with aListView
. You create one by subclassingListFragment
.
Key points:
- Make apps look different on different devices by putting separate layouts in
device-appropriate folders
. - Android keeps track of places you’ve visited within an app by adding them to the
back stack
as separatetransactions
. Pressing the Back button pops the last transaction off the back stack. - Use a
frame layout
to add, replace, or remove fragments programmatically usingfragment transactions
. - Begin the transaction by calling the
FragmentManager
beginTransaction()
method. This creates aFragmentTransaction
object. - Add, replace, and delete fragments using the
FragmentTransaction
add()
,replace()
, andremove()
methods. - Add a transaction to the back stack using the
FragmentTransaction
addToBackStack()
method. - Commit a transaction using the
FragmentTransaction
commit()
method. This applies all the updates in the transaction. - Save the state of a fragment’s variables in the
Fragment
onSaveInstanceState()
method. - Restore the state of a fragment’s variables in the
Fragment
onCreate()
method.
Key points:
- Fragments can contain other fragments.
- If you use the
android:onClick
attribute in a fragment, Android will look for a method of that name in the fragment’s parent activity. - Instead of using the
android:onClick
attribute in a fragment, make the fragment implement theView.OnClickListener
interface and implement itsonClick()
method. - If you use the
<fragment>
element in your layout, the fragment gets recreated when you rotate the device. If your fragment is dynamic, use afragment transaction
instead. - Fragments contain two methods for getting a fragment manager,
getFragmentManager()
andgetChildFragmentManager()
. getFragmentManager()
gets a reference to the fragment manager associated with the fragment’s parent activity. Any fragment transactions you create using this fragment manager are added to theback stack
as extra transactions.getChildFragmentManager()
gets a reference to the fragment manager associated with the fragment’s parent fragment. Any fragment transactions you create using this fragment manager arenested inside the parent fragment transaction
.
Key points:
- Enable swipe navigation using a
view pager
. - You tell a view pager about its pages by implementing a
fragment pager adapter
. - Use the fragment pager adapter’s
getCount()
method to tell the view pager how many pages it should have. Use itsgetItem()
method to tell it which fragment should appear on each page. - Add tab navigation by implementing a
tab layout
. Put the toolbar and tab layout inside anapp bar layout
in your layout code, then attach the tab layout to the view pager in your activity code. - The tab layout comes from the
Android Design Support Library
. This library helps you implement thematerial design guidelines
in your app. - Use a
coordinator layout
to coordinate animations between views. - Add scrollable content the coordinator layout can coordinate using a
nested scroll view
. - Use a
collapsing toolbar layout
to add a toolbar that collapses and grows in response to user scroll actions. - Use a
FAB
(floating action button) to promote common or important user actions. - A
snackbar
lets you display short messages that the user can interact with.
Key points:
Card views
andrecycler views
have their ownSupport Libraries
.- Add a card view to a layout using the
<android.support. v7.widget.CardView>
element. - Give the card view rounded corners using the
cardCornerRadius
attribute. This requires a namespace of"http://schemas.android.com/apk/res-auto"
. - Give the card view a drop shadow using the
cardElevation
attribute. This requires a namespace of"http://schemas.android.com/apk/res-auto"
. - Recycler views work with adapters that are subclasses of
RecyclerView.Adapter
. - When you create your own
RecyclerView.Adapter
, you must define the view holder and implement theonCreateViewHolder()
,onBindViewHolder()
, andgetItemCount()
methods. - You add a recycler view to a layout using the
<android.support. v7.widget.RecyclerView>
element. You give it a scrollbar using theandroid:scrollbars
attribute. - Use a layout manager to specify how items in a
recycler view
should be arranged. ALinearLayoutManager
arranges items in a linear list, aGridLayoutManager
arranges items in a grid, and aStaggeredGridLayoutManager
arranges items in a staggered grid.
Key points:
- Use a
navigation drawer
if you want to provide the user with a large number of shortcuts, or group them into sections. - Create a navigation drawer by adding a drawer layout to your activity’s layout. The drawer layout’s first element needs to be a view that defines the activity’s main content, usually a layout containing a
Toolbar
andFrameLayout
. Its second element defines the contents of the drawer, usually aNavigationView
. - The NavigationView comes from the
Design Support Library
. It controls most of the drawer’s behavior. - You add a header to your drawer by creating a layout for it, and adding the header’s resource ID to the navigation view’s
headerLayout
attribute. - You add items to the drawer by creating a menu resource, and adding the menu’s resource ID to the navigation view’s
menu
attribute. - Add items to the
menu resource
in the order in which you want them to appear in the drawer. - If you want to highlight which item in the drawer the user selects, add the menu items to a group and set the group’s
checkableBehavior
attribute to "single
". - Use an ActionBarDrawerToggle to display a “burger” icon in the activity’s toolbar. This provides a visual sign that the activity has a navigation drawer. Clicking on it opens the drawer.
- Respond to the user clicking on items in the drawer by making your activity implement the NavigationView.OnNavigationItemSelectedListener interface. Register the activity with the navigation view as a listener, then implement the
onNavigationItemSelected()
method. - Close the navigation drawer using the
DrawerLayout
closeDrawer()
method.
Key points:
- Android uses SQLite as its backend database to persist data.
- The
SQLiteDatabase
class gives you access to the SQLite database. - A SQLite helper lets you create and manage SQLite databases. You create a SQLite helper by extending the
SQLiteOpenHelper
class. - You must implement the
SQLiteOpenHelperonCreate()
andonUpgrade()
methods. - The database gets created the first time it needs to be accessed. You need to give the database a name and version number, starting at 1. If you don’t give the database a name, it will just get created in memory.
- The
onCreate()
method gets called when the database first gets created. - The
onUpgrade()
method gets called when the database needs to be upgraded. - Execute SQL using the
SQLiteDatabase
execSQL(String)
method. - Use the SQL
ALTER TABLE
command to change an existing table. UseRENAME TO
to rename the table, andADD COLUMN
to add a column. - Use the SQL
DROP TABLE
command to delete a table. - Add records to tables using the
insert()
method. - Update records using the
update()
method. - Remove records from tables using the
delete()
method.
- A
cursor
lets you read from and write to the database. - You create a cursor by calling the
SQLiteDatabasequery()
method. Behind the scenes, this builds a SQLSELECT
statement. - The
getWritableDatabase()
method returns aSQLiteDatabase
object that allows you to read from and write to the database. - The
getReadableDatabase()
returns aSQLiteDatabase
object. This gives you read-only access to the database. Itmay
also allow you to write to - the database, but this isn’t guaranteed. - Navigate through a cursor using the
moveTo*()
methods. - Get values from a cursor using the
get*()
methods. Close cursors and database connections after you’ve finished with them. - A
cursor adapter
is an adapter that works with cursors. UseSimpleCursorAdapter
to populate a list view with the values returned by a cursor.
- The CursorAdapter.changeCursor() method replaces the cursor currently used by a cursor adapter with a new cursor that you provide. It then closes the old cursor.
- Run your database code in a background thread using AsyncTask.
- onPreExecute() is used to set up the task. It’s called before the background task begins, and runs on the main event thread.
- doInBackground() runs in the background thread. It runs immediately after onPreExecute(). You can specify what type of parameters it has, and what its return type is.
- onProgressUpdate() is used to display progress. It runs in the main event thread when the doInBackground() method calls publishProgress().
- onPostExecute() is used to display the task outcome to the user when doInBackground has finished. It runs in the main event thread and takes the return value of doInBackground() as a parameter.
Key points:
- A
service
is an application component that can perform tasks in the background. It doesn’t have a user interface. - A
started service
can run in the background indefinitely, even when the activity that started it is destroyed. Once the operation is done, it stops itself. - A
bound service
is bound to another component such as an activity. The activity can interact with it and get results. - A
scheduled service
is one that’s scheduled to run at a particular time. - You can create a simple
started service
by extending theIntentService
class, overriding itsonHandleIntent()
method and adding a public constructor. - You declare services in
AndroidManifest.xml
using the<service>
element. - You start a
started service
using thestartService()
method. - When a
started service
is created, itsonCreate()
method gets called, followed byonStartCommand()
. If the service is anIntentService
,onHandleIntent()
is then called in a separate thread. When the service has finished running,onDestroy()
gets called before the service is destroyed. - The
IntentService
class inherits lifecycle methods from theService
class. - You log messages using the
Android.util.Log
class. You can view these messages in thelogcat
in Android Studio. - You create a
notification
using anotification builder
. Each notification must include a small icon, a title, and some text as a bare minimum. - A
heads-up notification
has its priority set to high, and vibrates the device or plays a sound when it’s issued. - You tell the notification which activity to start when it’s clicked by creating a
pending intent
and adding it to the notification as an action. - You issue the notification using a
notification manager
. You create a notification manager using Android’snotification service
.
- You create a bound service by extending the
Service
class. You define your ownBinder
object, and override theonBind()
method. - Bind a component to a service using the
bindService()
method. - Use a
ServiceConnection
so that your activity can get a reference to the service when it’s bound. - Unbind a component from a service using the
unbindService()
method. - When a bound service is created, its
onCreate()
method is called.onBind()
gets called when a component binds to the service. - When all components have unbound from the service, its
onUnbind()
method is called. - A bound service is destroyed when no components are bound to it. Its
onDestroy()
method is called just before the service is destroyed. - Use the
Android Location Services
to determine the current location of the device. - To get the current location of the device, you need to declare that the app requires
ACCESS_FINE_LOCATION
permission inAndroidManifest.xml
. - Get location updates using a
LocationListener
. - A
LocationManager
gives you access to Android’s Location Services. Get the best location provider available on the device using its -getBestProvider()
method. Request location updates from the provider usingrequestLocationUpdates()
. - Use
removeUpdates()
to stop getting location updates. - If your target SDK is API level 23 or above, check at runtime whether your app has been granted a permission using the
ContextCompat.checkSelfPermission()
method. - Request permissions at runtime using
ActivityCompat.requestPermissions()
. - Check the user’s response to a permission request by implementing the activity’s
onRequestPermissionsResult()
method.