Advanced Android Development – Concepts
https://www.gitbook.com/download/pdf/book/google-developer-training/android-developer-advanced-course-concepts
This is the concepts reference for the Advanced Android Development course, a training course created by the Google Developer Training team. This course builds on the skills you learned in the Android Developer Fundamentals course.
This course is intended to be taught in a classroom, but all the materials are available online, so if you like to learn by yourself, go ahead!
Prerequisites
The Advanced Android Development course is intended for experienced developers who have Java programming experience and know the fundamentals of how to build an Android app using the Java language. This course assumes you have mastered the topics in Units 1 to 4 of the Android Developer Fundamentals course.
Specifically, this course assumes you know how to:
- Install and use Android Studio.
- Run apps from Android Studio on both a device and an emulator.
- Create and use
Activity
instances. - Use
View
instances to create your app’s user interface - Enable interaction through click handlers.
- Create layouts using the Android Studio layout editor.
- Create and use
RecyclerView
andAdapter
classes. - Run tasks in the background.
- Save data in Android shared preferences.
- Save data in a local SQL database.
Course materials
The course materials include:
- This concept reference.
- A practical workbook, Advanced Android Development – Practicals, which guides you through creating Android apps to practice and perfect the skills you’re learning.
- Slide decks for optional use by instructors.
- Code in GitHub.
What topics are covered?
Unit 1: Expand the User Experience
Lesson 1: Fragments
Lesson 2: App Widgets
Lesson 3: Sensors
Unit 2: Make Your Apps Fast and Small
Lesson 4: Performance
Unit 3: Make Your Apps Accessible
Lesson 5: Localization
Lesson 6: Accessibility
Unit 4: Add Geo Features to Your Apps
Lesson 7: Location
Lesson 8: Places
Lesson 9: Mapping
Unit 5: Advanced Graphics and Views
Lesson 10: Custom Views
Lesson 11: Canvas
Lesson 12: Animations
Developed by the Google Developer Training Team
Last updated: October 2017
This work is licensed under a Creative Commons Attribution 4.0 International License
replace
FragmentTransaction replace (int containerViewId, Fragment fragment, String tag)
Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment)
for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String)
with the same arguments given here.
addToBackStack
FragmentTransaction addToBackStack (String name)
Add this transaction to the back stack. This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.
https://github.com/google-developer-training/android-advanced/tree/master/SongDetail
Summary
Adding a Fragment
dynamically:
- When adding a
Fragment
dynamically to anActivity
, the best practice for representing theFragment
as an instance in theActivity
is to create the instance with anewinstance()
factory method in theFragment
. - The
newinstance()
method can set aBundle
and usesetArguments(Bundle)
to supply the construction arguments for theFragment
. - Call the
newinstance()
method from theActivity
to create a new instance, and pass the specific data you need for thisBundle
.
Fragment lifecycle:
- The system calls
onAttach()
when aFragment
is first associated with anActivity
. UseonAttach()
to initialize essential components of theFragment
, such as a listener. - The system calls
onCreate()
when creating aFragment
. UseonCreate()
to initialize components of theFragment
that you want to retain when theFragment
is paused or stopped, then resumed. - The system calls
onCreateView()
to draw aFragment
UI for the first time. To draw a UI for yourFragment
, you must return the rootView
of yourFragment
layout from this method. You can returnnull
if theFragment
does not provide a UI. - When a
Fragment
is in the active or resumed state, it can access the hostActivity
instance withgetActivity()
and easily perform tasks such as finding aView
in theActivity
layout.
Calling Fragment
methods and saving its state:
- The host
Activity
can call methods in aFragment
by acquiring a reference to theFragment
fromFragmentManager
, usingfindFragmentById()
. - Save the
Fragment
state during the onSaveInstanceState() callback and restore it during eitheronCreate()
,onCreateView()
, oronActivityCreated()
.
To communicate from the host Activity
to a Fragment
, use a Bundle
and the following:
setArguments(Bundle)
: Supply the construction arguments for aFragment
. The arguments are retained across theFragment
lifecycle.getArguments()
: Return the arguments supplied tosetArguments(Bundle)
, if any.
To have a Fragment
communicate to its host Activity
, declare an interface in the Fragment
, and implement it in the Activity
.
- The interface in the
Fragment
defines a callback method to communicate to its hostActivity
. - The host
Activity
implements the callback method.
Turn on the Profile GPU Rendering tool
Ensure that developer options is turned on, and allow USB Debugging if prompted.
Go to Settings > Developer options and follow the steps as illustrated in the screenshot below.
- Scroll down to the Monitoring section.
- Select Profile GPU rendering.
-
Choose On screen as bars in the dialog box. Immediately, you see colored bars on your screen. The bars vary depending on your device and version of Android, so they may not look exactly as illustrated.
Developer options > Profile GPU rendering, select ” style=”border: 0px; box-sizing: border-box; -webkit-tap-highlight-color: transparent; text-size-adjust: none; -webkit-font-smoothing: antialiased; color: rgb(238, 238, 238) !important; background-color: rgb(34, 34, 34) !important; z-index: 1; font-size: inherit; break-inside: avoid; max-width: 485px; display: block; margin: 10px auto 0px;”>
-
Switch to the RecyclerView app and interact with it.
Note the following:
- Each bar represents one frame rendered.
-
If a bar goes above the green line, the frame took more than 16ms to render. Ideally, most of the bars stay below the green line most of the time.
This is not an absolute requirement. For example, when you first load an image, the bar may go above the green line, but users may not notice a problem, because they may expect to wait a moment for an image to load. Having some tall bars does not mean your app has a performance problem. However, if your app does have a performance problem, tall bars can give you a hint as to where to start looking.
-
The colors in each bar represent the different stages in rendering the frame. The colored sections visualize the stages and their relative times. The table below gives an explanation.
The image below shows the bars and color legend for a device that is running Android 6.0 or higher. The bars for older versions use different coloring. See the Profile GPU Rendering Walkthrough for the bar legend for older versions.
The following table shows the component bars in Android 6.0 and higher.
Color | Rendering stage | Description |
Swap buffers | Represents the time the CPU is waiting for the GPU to finish its work. If this part of the bar is tall, the app is doing too much work on the GPU. | |
Command issue | Represents the time spent by Android’s 2-D renderer as it issues commands to OpenGL to draw and redraw display lists. The height of this part of the bar is directly proportional to the sum of the time it takes for all the display lists to execute—more display lists equals a taller red segment of the bar. | |
Sync and upload | Represents the time it take to upload bitmap information to the GPU. If this part of the bar is tall, the app is taking considerable time loading large amounts of graphics. | |
Draw | Represents the time used to create and update the view’s display lists. If this part of the bar is tall, there may be a lot of custom view drawing, or a lot of work in onDraw methods. |
|
Measure and layout | Represents the amount of time spent on onLayout and onMeasure callbacks in the view hierarchy. A large segment indicates that the view hierarchy is taking a long time to process. | |
Animation | Represents the time spent evaluating animators. If this part of the bar is tall, your app could be using a custom animator that’s not performing well, or unintended work is happening as a result of properties being updated. | |
Input handling | Represents the time that the app spent executing code inside of an input event callback. If this part of the bar is tall, the app is spending too much time processing user input. Consider offloading such processing to a different thread. | |
Misc. time / Vsync delay | Represents the time that the app spends executing operations between consecutive frames. It might indicate too much processing happening in the UI thread that could be offloaded to a different thread. (Vsync is a display option found in some 3-D apps.) |
For example, if the green Input handling portion of the bar is tall, your app spends a lot of time handling input events, executing code called as a result of input event callbacks. To improve this, consider when and how your app requests user input, and whether you can handle it more efficiently.
Note that RecyclerView
scrolling can show up in the Input handling portion of the bar. RecyclerView
scrolls immediately when it processes the touch event. For this reason, processing the touch event needs to be as fast as possible.
If you spend time using the Profile GPU Rendering tool on your app, it will help you identify which parts of the UI interaction are slower than expected, and then you can take action to improve the speed of your app’s UI.
The following instructions are for Android 4.2 and higher. If you are running on an older version of Android, follow the instructions on the Analyze UI Performance with Systrace page.
- If you don’t already have the WordListSQL app, download the WordListSQL app from the
WordListSql_finished
folder on GitHub. Open the app in Android Studio and run it on your device. - From Android Studio, choose Tools > Android > Android Device Monitor. If you have instant run enabled, you may be asked to Disable ADB Integration. Click Yes.
Android Device Monitor launches in a separate window.
adb
as root
in order to get a trace. Type adb root
at the command line.Follow the steps as illustrated in the screenshot below:
-
Click
DDMS if it is not already selected. (1) in the screenshot below.
-
Select your app by package name in the Devices tab. (2) in the screenshot below.
-
Click the Systrace button
to initiate the trace. (3) in the screenshot below.
-
In the Systrace (Android System Trace) pop-up, choose your settings for the trace.
- Destination File: Where the trace is stored as an HTML file. Default is in your home directory with the filename
trace.html
. - Trace duration: Default is 5 seconds, and 15-30 seconds is a good time to choose.
- Trace Buffer Size: Start with the default.
- Enable Application Traces from: Make sure your app is visible and selected.
- Now select tags to enable. Choose all the Commonly Used Tags. In the Advanced Options, choose Power Management and Database. Use fewer tags to limit the size and complexity of the trace output.
- Destination File: Where the trace is stored as an HTML file. Default is in your home directory with the filename
-
Click OK to start tracing. A pop-up appears, indicating that tracing is active.
- Interact with the WordListSQL app on your device. Create, edit, and delete an item.
- When time is up, the pop-up closes, and your trace is done.
Lesson 11: Canvas
Solution code
Android Studio project: SimpleCanvas.
Summary
- To draw on the display of a mobile device with Android you need a
View
, aCanvas
, aPaint
, and aBitmap
object. - The
Bitmap
is the physical drawing surface. TheCanvas
provides an API to draw on the bitmap, thePaint
is for styling what you draw, and theView
displays theBitmap
. - You create a
Bitmap
, associate it with aView
, create aCanvas
with aPaint
object for theBitmap
, and then you can draw. - You must
invalidate()
the view when your are done drawing, so that the Android System redraws the display. - All drawing happens on the UI thread, so performance matters.