The Android winds of change From Kit-Kat to L, and the power of - - PowerPoint PPT Presentation
The Android winds of change From Kit-Kat to L, and the power of - - PowerPoint PPT Presentation
The Android winds of change From Kit-Kat to L, and the power of saving power Why are you here? Info on the new IDE, and setting up projects Want to know the changes L brings to your Kit-Kat apps How to analyse your apps
SLIDE 1
SLIDE 2
Why are you here?
- Info on the new IDE, and setting up projects
- Want to know the changes L brings to your Kit-Kat apps
- How to analyse your app’s performance
SLIDE 3
Android
- Java based
- Approximately annual upgrade
- Previous version: Kit-Kat
- Based on Holo design
- Next version: Something starting with L
- Based on Material design
SLIDE 4
The app: Pokedex
- Master/Detail view of Pokemon
- Originally designed for Android Kit-Kat
SLIDE 5
The migration
- Change the structure of the app
- Style it
- Improve performance
SLIDE 6
The IDE & project setup
SLIDE 7
A comparison
- Used Eclipse with ADT plugin to develop
- Ant to build, especially via CI
- Manual dependency management
Build Tool Dependency Management Updates Eclipse with ADT Ant Manual via lib imports ADT plugin not actively being updated Android Studio Gradle Automatic via Gradle Constantly being updated with new IDE features
SLIDE 8
What do I need to change?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> …
- <uses-sdk
android:minSdkVersion="15" android:targetSdkVersion="18" />
- …
</manifest>
SLIDE 9
What do I need to change?
android { compileSdkVersion 'android-L' buildToolsVersion '20.0.0' defaultConfig { targetSdkVersion 'L' } } dependencies { compile 'com.android.support:support-v4:+' compile 'com.android.support:cardview-v7:+' compile 'com.android.support:recyclerview-v7:+' compile 'com.android.support:palette-v7:+' }
SLIDE 10
New components
SLIDE 11
RecyclerView
- More advanced and flexible than ListView
- Forces the ViewHolder pattern
- Recycling process is more efficient
- Requires an external LayoutManager
SLIDE 12
RecyclerView in action
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id=“@+id/my_recycler_view"> </android.support.v7.widget.RecyclerView>
SLIDE 13
RecyclerView in action
protected void onCreate(Bundle savedInstanceState) { // Set the content view … RecyclerView recyclerView =
- (RecyclerView)findViewById(R.id.my_recycler_view);
RecyclerView.LayoutManager layoutManager =
- new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager); … // Setup adapter }
SLIDE 14
ViewHolder pattern?
Scroll RecyclerView up View scrolls off screen View is held off screen View is recycled when needed avoiding the need to recreate the View, thus improving app performance
SLIDE 15
Implementing the ViewHolder pattern
4
Bind the data to the element’s view in
- nBindViewHolder()
3
Inflate the element’s view in RecyclerView.Adapter’s
- nCreateViewHolder()
2
Create a RecyclerView.ViewHolder Create the RecyclerView.Adapter to use the ViewHolder
1
SLIDE 16
Implementing the ViewHolder pattern
4
Bind the data to the element’s view in
- nBindViewHolder()
3
Inflate the element’s view in RecyclerView.Adapter’s
- nCreateViewHolder()
2
Create a RecyclerView.ViewHolder Create the RecyclerView.Adapter to use the ViewHolder
1
SLIDE 17
Implementing the ViewHolder pattern
4
Bind the data to the element’s view in
- nBindViewHolder()
3
Inflate the element’s view in RecyclerView.Adapter’s
- nCreateViewHolder()
2
Create a RecyclerView.ViewHolder Create the RecyclerView.Adapter to use the ViewHolder
1
SLIDE 18
Implementing the ViewHolder pattern
4
Bind the data to the element’s view in
- nBindViewHolder()
3
Inflate the element’s view in RecyclerView.Adapter’s
- nCreateViewHolder()
2
Create a RecyclerView.ViewHolder Create the RecyclerView.Adapter to use the ViewHolder
1
SLIDE 19
How does this look?
public class PokedexHolder extends RecyclerView.ViewHolder { public CardView card; public ImageView image; public TextView text;
- public PokedexHolder(View v) {
super(v); card = (CardView) v.findViewById(R.id.card_view); image = (ImageView) v.findViewById(R.id.img_image); text = (TextView) v.findViewById(R.id.txt_name); } }
SLIDE 20
How does this look?
public class PokemonArrayAdapter
- extends RecyclerView.Adapter<PokedexHolder>
- implements View.OnClickListener {
@Override public PokedexHolder onCreateViewHolder(ViewGroup viewGroup, int pos) { View v = LayoutInflater.from(viewGroup.getContext())
- .inflate(R.layout.row_pokemon, viewGroup, false);
PokedexHolder holder = new PokedexHolder(v); holder.card.setOnClickListener(this); return holder; } … }
SLIDE 21
How does this look?
pubic class PokemonAdapter { … public void onBindViewHolder(
- PokedexHolder pokedexHolder, int position) {
Pokemon p = getPokemonFromList(position);
- pokedexHolder.image.setImageDrawable(
- context.getResources().getDrawable(p.getImage()));
pokedexHolder.text.setText(p.getName()); } }
SLIDE 22
How does this look?
protected void onCreate(Bundle savedInstanceState) {
- PokemonArrayAdapter adapter =
- new PokemonArrayAdapter(this, items);
- recyclerView.setAdapter(adapter);
}
SLIDE 23
CardView
- Material design > Paper > CardView
- Mobile, Tablet, Wearables(Glass, Watch), TV, Auto
- Rounded corners
- Elevations / Shadows
SLIDE 24
CardView
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" card_view:cardCornerRadius="4dp"> <!-- Insert card layout here --> </android.support.v7.widget.CardView>
SLIDE 25
Progress
SLIDE 26
Material design: What is it?
SLIDE 27
What is Material design?
- More paper look and feel
- To provide a way to the user to relate to elements on devices using:
- cards
- shadows
- elevations
SLIDE 28
How does it differ from Kit-Kat?
- Bright bold colours vs splashes of colour
- Motion to indicate actions have been performed
- Custom palettes
- Elevations and shadows
SLIDE 29
Themes
- Themes aren’t new
- Base theme: “Theme.material”
- Dark, Light, Light with DarkActionBar
SLIDE 30
Colours
- Wider gamut of colours
- Combinations of primary and
secondary colours
SLIDE 31
Palettes & named colours
- Custom palettes
- Named colours
SLIDE 32
Changing the Pokedex theme
SLIDE 33
Changing the Pokedex theme
<resources> <!-- Base application theme. --> <style name=“AppTheme" parent="android:Theme.Material.Light"> <item name="android:colorPrimary">@color/red</item> <item name="android:textColorPrimary">@color/white</item> <item name="android:colorPrimaryDark">@color/dark_red</item> <item name="android:windowBackground">@color/green</item> <item name="android:navigationBarColor">@color/red</item> </style> </resources>
SLIDE 34
Adding custom colours
public void onBindViewHolder(...) { Palette palette = Palette.generate(image); if (palette.getDarkMutedColor() != null) { holder.text.setBackgroundColor(
- palette.getDarkMutedColor().getRgb());
} if (palette.getVibrantColor() != null) { holder.text.setTextColor(
- palette.getVibrantColor().getRgb());
} }
SLIDE 35
Visually complete!
SLIDE 36
But the battery is draining quickly…
SLIDE 37
But the battery is draining quickly…
We need to fix this before it goes to the Play Store!
SLIDE 38
Battery Performance
SLIDE 39
Project Volta
- Performance improvements in Android platform
- Tools to analyse application efficiency
- Increase user awareness of power consumption
SLIDE 40
Project Volta
Waking a device for 1 sec = 2 mins of standby time lost
SLIDE 41
Battery stats
adb shell dumpsys batterystats --charged <package-name>
SLIDE 42
Battery Historian
Python script used to create an HTML visualisation
- f the data obtained from batterystats command
Battery Stats Battery Historian HTML Visualisation
SLIDE 43
What does the output look like?
SLIDE 44
What can we infer from this graph?
SLIDE 45
What can we infer from this graph?
SLIDE 46
Pokedex Performance
SLIDE 47
Power Management Strategies
SLIDE 48
Being lazy is good
- Make apps Lazy first
- Reduce number of time app is active
- Coalesce actions together
- Defer actions to a later time
- eg: when charging
SLIDE 49
Consider this
What is the longest time I am willing to wait to complete this task?
SLIDE 50
JobScheduler
- Allows you to schedule jobs to occur at a later time.
SLIDE 51
What is a job?
- A job is a non user-facing network call
eg:
- CPU intensive operations you’d prefer when the user isn’t around
- Some job you need to perform periodically, or in the future
SLIDE 52
Create a job example #1
Every fifteen hours, perform some database clean-up and upload some logs to the server
SLIDE 53
Create a job example #1
Every fifteen hours, perform some database clean-up and upload some logs to the server
- JobInfo uploadJob =
- new JobInfo.Builder(mJobId, mServiceComponent)
- .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
- .setPeriodic(15 * DateUtils.HOURS_IN_MILLIS)
- .setRequiresCharging(true)
- .build();
SLIDE 54
Create a job example #1
Every fifteen hours, perform some database clean-up and upload some logs to the server
- JobInfo uploadJob =
- new JobInfo.Builder(mJobId, mServiceComponent)
- .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
- .setPeriodic(15 * DateUtils.HOURS_IN_MILLIS)
- .setRequiresCharging(true)
- .build();
Job ID
SLIDE 55
Create a job example #1
Every fifteen hours, perform some database clean-up and upload some logs to the server
- JobInfo uploadJob =
- new JobInfo.Builder(mJobId, mServiceComponent)
- .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
- .setPeriodic(15 * DateUtils.HOURS_IN_MILLIS)
- .setRequiresCharging(true)
- .build();
Job Endpoint
SLIDE 56
Create a job example #1
Every fifteen hours, perform some database clean-up and upload some logs to the server
- JobInfo uploadJob =
- new JobInfo.Builder(mJobId, mServiceComponent)
- .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
- .setPeriodic(15 * DateUtils.HOURS_IN_MILLIS)
- .setRequiresCharging(true)
- .build();
Network Type
SLIDE 57
Create a job example #1
Every fifteen hours, perform some database clean-up and upload some logs to the server
- JobInfo uploadJob =
- new JobInfo.Builder(mJobId, mServiceComponent)
- .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
- .setPeriodic(15 * DateUtils.HOURS_IN_MILLIS)
- .setRequiresCharging(true)
- .build();
Periodically recur
SLIDE 58
Create a job example #1
Every fifteen hours, perform some database clean-up and upload some logs to the server
- JobInfo uploadJob =
- new JobInfo.Builder(mJobId, mServiceComponent)
- .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
- .setPeriodic(15 * DateUtils.HOURS_IN_MILLIS)
- .setRequiresCharging(true)
- .build();
Charging constraint
SLIDE 59
Schedule Criteria
- Network activity aware
- Idle mode
- Run task while charging
- Metered/unmetered
SLIDE 60
Schedule features
- Persistence
- Retry / back-off
- One-time / periodic
SLIDE 61
Create a job example #2
Schedule a job to run five seconds from now, but before fifteen minutes have passed
SLIDE 62
Create a job example #2
Schedule a job to run five seconds from now, but before fifteen minutes have passed
- JobInfo job = new JobInfo.Builder(mJobId + 1, mServiceComponent)
- .setMinimumLatency(5 * DateUtils.SECONDS_IN_MILLIS)
- .setOverrideDeadline(15 * DateUtils.MINUTES_IN_MILLIS)
- .build();
SLIDE 63
Create a job example #2
Schedule a job to run five seconds from now, but before fifteen minutes have passed
- JobInfo job = new JobInfo.Builder(mJobId + 1, mServiceComponent)
- .setMinimumLatency(5 * DateUtils.SECONDS_IN_MILLIS)
- .setOverrideDeadline(15 * DateUtils.MINUTES_IN_MILLIS)
- .build();
Job ID
SLIDE 64
Create a job example #2
Schedule a job to run five seconds from now, but before fifteen minutes have passed
- JobInfo job = new JobInfo.Builder(mJobId + 1, mServiceComponent)
- .setMinimumLatency(5 * DateUtils.SECONDS_IN_MILLIS)
- .setOverrideDeadline(15 * DateUtils.MINUTES_IN_MILLIS)
- .build();
Job Endpoint
SLIDE 65
Create a job example #2
Schedule a job to run five seconds from now, but before fifteen minutes have passed
- JobInfo job = new JobInfo.Builder(mJobId + 1, mServiceComponent)
- .setMinimumLatency(5 * DateUtils.SECONDS_IN_MILLIS)
- .setOverrideDeadline(15 * DateUtils.MINUTES_IN_MILLIS)
- .build();
Start Delay
SLIDE 66
Create a job example #2
Schedule a job to run five seconds from now, but before fifteen minutes have passed
- JobInfo job = new JobInfo.Builder(mJobId + 1, mServiceComponent)
- .setMinimumLatency(5 * DateUtils.SECONDS_IN_MILLIS)
- .setOverrideDeadline(15 * DateUtils.MINUTES_IN_MILLIS)
- .build();
Deadline
SLIDE 67
Creating an endpoint
- System calls the onStartJob() of your service
- System
Service
- nStartJob()
SLIDE 68
Creating an endpoint
- System calls the onStartJob() of your service
- System
Service
- nStartJob() {
}
SLIDE 69
Creating an endpoint
- System calls the onStartJob() of your service
- Perform logic
System Service
- nStartJob() {
… }
SLIDE 70
Creating an endpoint
- System calls the onStartJob() of your service
- Perform logic
- Call jobFinished() when job is complete
System Service
- nStartJob() {
… jobFinished(); }
SLIDE 71
Creating an endpoint
- System calls the onStartJob() of your service
- Perform logic
- Call jobFinished() when job is complete
System Service
- nStartJob() {
… jobFinished(); }
SLIDE 72
Criteria has changed and not valid
System Service
- nStartJob()
SLIDE 73
Criteria has changed and not valid
- System calls the onStopJob()
- System
Service
- nStartJob()
- nStopJob()
SLIDE 74
Criteria has changed and not valid
- System calls the onStopJob()
- System
Service
- nStartJob()
- nStopJob()
SLIDE 75
Criteria has changed and not valid
- System calls the onStopJob()
- System
Service
- nStopJob() {
- }
SLIDE 76
Criteria has changed and not valid
- System calls the onStopJob()
- Perform logic
System Service
- nStopJob() {
…
- }
SLIDE 77
Criteria has changed and not valid
- System calls the onStopJob()
- Perform logic
- Call jobFinished() when job is complete
System Service
- nStopJob() {
… jobFinished(); }
SLIDE 78
Criteria has changed and not valid
- System calls the onStopJob()
- Perform logic
- Call jobFinished() when job is complete
System Service
- nStopJob() {
… jobFinished(); }
SLIDE 79
Pokedex Performance
Before After
SLIDE 80
Battery Historian
http://github.com/google/battery-historian
SLIDE 81
What just happened
- Changed structure of app
- New IDE
- RecyclerView, CardView
- Applied colour
- Themes
- Custom colour palettes
- Improved performance
- JobScheduler
- Battery Historian
SLIDE 82
Where to from here?
- Download latest Android Studio with Android L-Preview API
- Read the Google docs on Material and Android L-Preview
- Start coding!!!
SLIDE 83
Final thoughts…
SLIDE 84
Questions?
www.outware.com.au
- OMPodcast